mirror of
				https://github.com/qgis/QGIS.git
				synced 2025-11-04 00:04:25 -05:00 
			
		
		
		
	Add a flag argument to QgsFeatureSink::addFeatures
Flags can be used to control how features are added to the sink. For now, there's only a single flag available - FastInsert. When FastInsert is set, faster inserts will be use at the cost of updating the passed features to reflect changes made at the provider. This includes skipping the update of the passed feature IDs to match the resulting feature IDs for the feature within the data provider. Individual sink subclasses may or may not choose to respect this flag, depending on whether or not skipping this update represents a significant speed boost for the operation. QgsVectorLayer always ignores the flag - feature ids are required for the featureAdded signal to be correctly emitted, and it's expected that performance critical applications will add features directly to a data provider instead of via QgsVectorLayer's edit buffer.
This commit is contained in:
		
							parent
							
								
									7aec4d1a5f
								
							
						
					
					
						commit
						fc339f9ac5
					
				@ -22,33 +22,44 @@ class QgsFeatureSink
 | 
			
		||||
%End
 | 
			
		||||
  public:
 | 
			
		||||
 | 
			
		||||
    enum Flag
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
      FastInsert,
 | 
			
		||||
    };
 | 
			
		||||
    typedef QFlags<QgsFeatureSink::Flag> Flags;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    virtual ~QgsFeatureSink();
 | 
			
		||||
 | 
			
		||||
    virtual bool addFeature( QgsFeature &feature );
 | 
			
		||||
    virtual bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = 0 );
 | 
			
		||||
%Docstring
 | 
			
		||||
 Adds a single ``feature`` to the sink.
 | 
			
		||||
 Adds a single ``feature`` to the sink. Feature addition behavior is controlled by the specified ``flags``.
 | 
			
		||||
.. seealso:: addFeatures()
 | 
			
		||||
 :return: true in case of success and false in case of failure
 | 
			
		||||
 :rtype: bool
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &features ) = 0;
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = 0 ) = 0;
 | 
			
		||||
%Docstring
 | 
			
		||||
 Adds a list of ``features`` to the sink.
 | 
			
		||||
 Adds a list of ``features`` to the sink. Feature addition behavior is controlled by the specified ``flags``.
 | 
			
		||||
.. seealso:: addFeature()
 | 
			
		||||
 :return: true in case of success and false in case of failure
 | 
			
		||||
 :rtype: bool
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureIterator &iterator );
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureIterator &iterator, QgsFeatureSink::Flags flags = 0 );
 | 
			
		||||
%Docstring
 | 
			
		||||
 Adds all features from the specified ``iterator`` to the sink.
 | 
			
		||||
 Adds all features from the specified ``iterator`` to the sink. Feature addition behavior is controlled by the specified ``flags``.
 | 
			
		||||
 :return: true if all features were added successfully, or false if any feature could not be added
 | 
			
		||||
 :rtype: bool
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
QFlags<QgsFeatureSink::Flag> operator|(QgsFeatureSink::Flag f1, QFlags<QgsFeatureSink::Flag> f2);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class QgsProxyFeatureSink : QgsFeatureSink
 | 
			
		||||
{
 | 
			
		||||
@ -73,9 +84,9 @@ class QgsProxyFeatureSink : QgsFeatureSink
 | 
			
		||||
%Docstring
 | 
			
		||||
 Constructs a new QgsProxyFeatureSink which forwards features onto a destination ``sink``.
 | 
			
		||||
%End
 | 
			
		||||
    virtual bool addFeature( QgsFeature &feature );
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &features );
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureIterator &iterator );
 | 
			
		||||
    virtual bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = 0 );
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = 0 );
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureIterator &iterator, QgsFeatureSink::Flags flags = 0 );
 | 
			
		||||
 | 
			
		||||
    QgsFeatureSink *destinationSink();
 | 
			
		||||
%Docstring
 | 
			
		||||
 | 
			
		||||
@ -53,9 +53,9 @@ Constructor
 | 
			
		||||
.. seealso:: crs()
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
    virtual bool addFeature( QgsFeature &feature );
 | 
			
		||||
    virtual bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = 0 );
 | 
			
		||||
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &features );
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = 0 );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    int count() const;
 | 
			
		||||
 | 
			
		||||
@ -197,7 +197,7 @@ Bitmask of all provider's editing capabilities
 | 
			
		||||
 \param enumList reference to the list to fill
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &flist /In,Out/ );
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &flist /In,Out/, QgsFeatureSink::Flags flags = 0 );
 | 
			
		||||
 | 
			
		||||
    virtual bool deleteFeatures( const QgsFeatureIds &id );
 | 
			
		||||
%Docstring
 | 
			
		||||
 | 
			
		||||
@ -522,9 +522,9 @@ Retrieves error message
 | 
			
		||||
 :rtype: str
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
    virtual bool addFeature( QgsFeature &feature );
 | 
			
		||||
    virtual bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = 0 );
 | 
			
		||||
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &features );
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = 0 );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    bool addFeature( QgsFeature &feature, QgsFeatureRenderer *renderer, QgsUnitTypes::DistanceUnit outputUnit = QgsUnitTypes::DistanceMeters );
 | 
			
		||||
 | 
			
		||||
@ -928,7 +928,7 @@ Return the provider type for this layer
 | 
			
		||||
 :rtype: QgsFeatureIterator
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
    virtual bool addFeature( QgsFeature &feature );
 | 
			
		||||
    virtual bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = 0 );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    bool updateFeature( QgsFeature &f );
 | 
			
		||||
@ -1281,7 +1281,7 @@ Delete an attribute field (but does not commit it)
 | 
			
		||||
 :rtype: bool
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &features );
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = 0 );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    bool deleteFeature( QgsFeatureId fid );
 | 
			
		||||
 | 
			
		||||
@ -114,9 +114,9 @@ class QgsVectorLayerExporter : QgsFeatureSink
 | 
			
		||||
 :rtype: int
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &features );
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = 0 );
 | 
			
		||||
 | 
			
		||||
    virtual bool addFeature( QgsFeature &feature );
 | 
			
		||||
    virtual bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = 0 );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    ~QgsVectorLayerExporter();
 | 
			
		||||
 | 
			
		||||
@ -323,7 +323,7 @@ QgsCoordinateReferenceSystem QgsMemoryProvider::crs() const
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool QgsMemoryProvider::addFeatures( QgsFeatureList &flist )
 | 
			
		||||
bool QgsMemoryProvider::addFeatures( QgsFeatureList &flist, Flags )
 | 
			
		||||
{
 | 
			
		||||
  // whether or not to update the layer extent on the fly as we add features
 | 
			
		||||
  bool updateExtent = mFeatures.isEmpty() || !mExtent.isEmpty();
 | 
			
		||||
 | 
			
		||||
@ -50,7 +50,7 @@ class QgsMemoryProvider : public QgsVectorDataProvider
 | 
			
		||||
    virtual QgsWkbTypes::Type wkbType() const override;
 | 
			
		||||
    virtual long featureCount() const override;
 | 
			
		||||
    virtual QgsFields fields() const override;
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &flist ) override;
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &flist, QgsFeatureSink::Flags flags = 0 ) override;
 | 
			
		||||
    virtual bool deleteFeatures( const QgsFeatureIds &id ) override;
 | 
			
		||||
    virtual bool addAttributes( const QList<QgsField> &attributes ) override;
 | 
			
		||||
    virtual bool renameAttributes( const QgsFieldNameMap &renamedAttributes ) override;
 | 
			
		||||
 | 
			
		||||
@ -17,24 +17,27 @@
 | 
			
		||||
 | 
			
		||||
#include "qgsfeaturestore.h"
 | 
			
		||||
 | 
			
		||||
bool QgsFeatureSink::addFeature( QgsFeature &feature )
 | 
			
		||||
bool QgsFeatureSink::addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags )
 | 
			
		||||
{
 | 
			
		||||
  QgsFeatureList features;
 | 
			
		||||
  features << feature;
 | 
			
		||||
  bool result = addFeatures( features );
 | 
			
		||||
  bool result = addFeatures( features, flags );
 | 
			
		||||
 | 
			
		||||
  // need to update the passed feature reference to the updated copy from the features list
 | 
			
		||||
  feature = features.at( 0 );
 | 
			
		||||
  if ( !( flags & FastInsert ) )
 | 
			
		||||
  {
 | 
			
		||||
    // need to update the passed feature reference to the updated copy from the features list
 | 
			
		||||
    feature = features.at( 0 );
 | 
			
		||||
  }
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool QgsFeatureSink::addFeatures( QgsFeatureIterator &iterator )
 | 
			
		||||
bool QgsFeatureSink::addFeatures( QgsFeatureIterator &iterator, QgsFeatureSink::Flags flags )
 | 
			
		||||
{
 | 
			
		||||
  QgsFeature f;
 | 
			
		||||
  bool result = true;
 | 
			
		||||
  while ( iterator.nextFeature( f ) )
 | 
			
		||||
  {
 | 
			
		||||
    result = result && addFeature( f );
 | 
			
		||||
    result = result && addFeature( f, flags );
 | 
			
		||||
  }
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -34,30 +34,47 @@ class CORE_EXPORT QgsFeatureSink
 | 
			
		||||
{
 | 
			
		||||
  public:
 | 
			
		||||
 | 
			
		||||
    //! Flags controlling how features are added to a sink.
 | 
			
		||||
    enum Flag
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
        * Use faster inserts, at the cost of updating the passed features to reflect changes made at the provider.
 | 
			
		||||
        * This includes skipping the update of the passed feature IDs to match the resulting feature IDs for the
 | 
			
		||||
        * feature within the data provider.
 | 
			
		||||
        * Individual sink subclasses may or may not choose to respect this flag, depending on whether or not
 | 
			
		||||
        * skipping this update represents a significant speed boost for the operation.
 | 
			
		||||
        */
 | 
			
		||||
      FastInsert = 1 << 1,
 | 
			
		||||
    };
 | 
			
		||||
    Q_DECLARE_FLAGS( Flags, Flag )
 | 
			
		||||
 | 
			
		||||
    virtual ~QgsFeatureSink() = default;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a single \a feature to the sink.
 | 
			
		||||
     * Adds a single \a feature to the sink. Feature addition behavior is controlled by the specified \a flags.
 | 
			
		||||
     * \see addFeatures()
 | 
			
		||||
     * \returns true in case of success and false in case of failure
 | 
			
		||||
     */
 | 
			
		||||
    virtual bool addFeature( QgsFeature &feature );
 | 
			
		||||
    virtual bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = 0 );
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a list of \a features to the sink.
 | 
			
		||||
     * Adds a list of \a features to the sink. Feature addition behavior is controlled by the specified \a flags.
 | 
			
		||||
     * \see addFeature()
 | 
			
		||||
     * \returns true in case of success and false in case of failure
 | 
			
		||||
     */
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &features ) = 0;
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = 0 ) = 0;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds all features from the specified \a iterator to the sink.
 | 
			
		||||
     * Adds all features from the specified \a iterator to the sink. Feature addition behavior is controlled by the specified \a flags.
 | 
			
		||||
     * \returns true if all features were added successfully, or false if any feature could not be added
 | 
			
		||||
     */
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureIterator &iterator );
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureIterator &iterator, QgsFeatureSink::Flags flags = 0 );
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Q_DECLARE_OPERATORS_FOR_FLAGS( QgsFeatureSink::Flags )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \class QgsProxyFeatureSink
 | 
			
		||||
@ -80,9 +97,9 @@ class CORE_EXPORT QgsProxyFeatureSink : public QgsFeatureSink
 | 
			
		||||
     * Constructs a new QgsProxyFeatureSink which forwards features onto a destination \a sink.
 | 
			
		||||
     */
 | 
			
		||||
    QgsProxyFeatureSink( QgsFeatureSink *sink );
 | 
			
		||||
    bool addFeature( QgsFeature &feature ) override { return mSink->addFeature( feature ); }
 | 
			
		||||
    bool addFeatures( QgsFeatureList &features ) override { return mSink->addFeatures( features ); }
 | 
			
		||||
    bool addFeatures( QgsFeatureIterator &iterator ) override { return mSink->addFeatures( iterator ); }
 | 
			
		||||
    bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = 0 ) override { return mSink->addFeature( feature, flags ); }
 | 
			
		||||
    bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = 0 ) override { return mSink->addFeatures( features, flags ); }
 | 
			
		||||
    bool addFeatures( QgsFeatureIterator &iterator, QgsFeatureSink::Flags flags = 0 ) override { return mSink->addFeatures( iterator, flags ); }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the destination QgsFeatureSink which the proxy will forward features to.
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,7 @@ void QgsFeatureStore::setFields( const QgsFields &fields )
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool QgsFeatureStore::addFeature( QgsFeature &feature )
 | 
			
		||||
bool QgsFeatureStore::addFeature( QgsFeature &feature, Flags )
 | 
			
		||||
{
 | 
			
		||||
  QgsFeature f( feature );
 | 
			
		||||
  f.setFields( mFields );
 | 
			
		||||
@ -43,12 +43,12 @@ bool QgsFeatureStore::addFeature( QgsFeature &feature )
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool QgsFeatureStore::addFeatures( QgsFeatureList &features )
 | 
			
		||||
bool QgsFeatureStore::addFeatures( QgsFeatureList &features, Flags flags )
 | 
			
		||||
{
 | 
			
		||||
  QgsFeatureList::iterator fIt = features.begin();
 | 
			
		||||
  for ( ; fIt != features.end(); ++fIt )
 | 
			
		||||
  {
 | 
			
		||||
    addFeature( *fIt );
 | 
			
		||||
    addFeature( *fIt, flags );
 | 
			
		||||
  }
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -61,8 +61,8 @@ class CORE_EXPORT QgsFeatureStore : public QgsFeatureSink
 | 
			
		||||
     */
 | 
			
		||||
    void setCrs( const QgsCoordinateReferenceSystem &crs ) { mCrs = crs; }
 | 
			
		||||
 | 
			
		||||
    bool addFeature( QgsFeature &feature ) override;
 | 
			
		||||
    bool addFeatures( QgsFeatureList &features ) override;
 | 
			
		||||
    bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = 0 ) override;
 | 
			
		||||
    bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = 0 ) override;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the number of features contained in the store.
 | 
			
		||||
 | 
			
		||||
@ -62,9 +62,10 @@ QString QgsVectorDataProvider::dataComment() const
 | 
			
		||||
  return QString();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool QgsVectorDataProvider::addFeatures( QgsFeatureList &flist )
 | 
			
		||||
bool QgsVectorDataProvider::addFeatures( QgsFeatureList &flist, Flags flags )
 | 
			
		||||
{
 | 
			
		||||
  Q_UNUSED( flist );
 | 
			
		||||
  Q_UNUSED( flags );
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -224,7 +224,7 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider, public QgsFeat
 | 
			
		||||
     */
 | 
			
		||||
    virtual void enumValues( int index, QStringList &enumList SIP_OUT ) const { Q_UNUSED( index ); enumList.clear(); }
 | 
			
		||||
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &flist SIP_INOUT ) override;
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &flist SIP_INOUT, QgsFeatureSink::Flags flags = 0 ) override;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Deletes one or more features from the provider. This requires the DeleteFeatures capability.
 | 
			
		||||
 | 
			
		||||
@ -1836,12 +1836,12 @@ QString QgsVectorFileWriter::errorMessage()
 | 
			
		||||
  return mErrorMessage;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool QgsVectorFileWriter::addFeature( QgsFeature &feature )
 | 
			
		||||
bool QgsVectorFileWriter::addFeature( QgsFeature &feature, Flags )
 | 
			
		||||
{
 | 
			
		||||
  return addFeature( feature, nullptr, QgsUnitTypes::DistanceMeters );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool QgsVectorFileWriter::addFeatures( QgsFeatureList &features )
 | 
			
		||||
bool QgsVectorFileWriter::addFeatures( QgsFeatureList &features, Flags )
 | 
			
		||||
{
 | 
			
		||||
  QgsFeatureList::iterator fIt = features.begin();
 | 
			
		||||
  bool result = true;
 | 
			
		||||
 | 
			
		||||
@ -516,8 +516,8 @@ class CORE_EXPORT QgsVectorFileWriter : public QgsFeatureSink
 | 
			
		||||
    //! Retrieves error message
 | 
			
		||||
    QString errorMessage();
 | 
			
		||||
 | 
			
		||||
    bool addFeature( QgsFeature &feature ) override;
 | 
			
		||||
    bool addFeatures( QgsFeatureList &features ) override;
 | 
			
		||||
    bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = 0 ) override;
 | 
			
		||||
    bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = 0 ) override;
 | 
			
		||||
 | 
			
		||||
    //! Add feature to the currently opened data source
 | 
			
		||||
    bool addFeature( QgsFeature &feature, QgsFeatureRenderer *renderer, QgsUnitTypes::DistanceUnit outputUnit = QgsUnitTypes::DistanceMeters );
 | 
			
		||||
 | 
			
		||||
@ -940,7 +940,7 @@ QgsFeatureIterator QgsVectorLayer::getFeatures( const QgsFeatureRequest &request
 | 
			
		||||
  return QgsFeatureIterator( new QgsVectorLayerFeatureIterator( new QgsVectorLayerFeatureSource( this ), true, request ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool QgsVectorLayer::addFeature( QgsFeature &feature )
 | 
			
		||||
bool QgsVectorLayer::addFeature( QgsFeature &feature, Flags )
 | 
			
		||||
{
 | 
			
		||||
  if ( !mValid || !mEditBuffer || !mDataProvider )
 | 
			
		||||
    return false;
 | 
			
		||||
@ -2587,7 +2587,7 @@ QgsFeatureIterator QgsVectorLayer::getSelectedFeatures( QgsFeatureRequest reques
 | 
			
		||||
  return getFeatures( request );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool QgsVectorLayer::addFeatures( QgsFeatureList &features )
 | 
			
		||||
bool QgsVectorLayer::addFeatures( QgsFeatureList &features, Flags )
 | 
			
		||||
{
 | 
			
		||||
  if ( !mEditBuffer || !mDataProvider )
 | 
			
		||||
    return false;
 | 
			
		||||
 | 
			
		||||
@ -900,7 +900,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
 | 
			
		||||
      return getFeatures( QgsFeatureRequest( rectangle ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool addFeature( QgsFeature &feature ) override;
 | 
			
		||||
    bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = 0 ) override;
 | 
			
		||||
 | 
			
		||||
    /** Updates an existing feature. This method needs to query the datasource
 | 
			
		||||
        on every call. Consider using changeAttributeValue() or
 | 
			
		||||
@ -1222,7 +1222,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
 | 
			
		||||
     */
 | 
			
		||||
    bool deleteAttributes( QList<int> attrs );
 | 
			
		||||
 | 
			
		||||
    bool addFeatures( QgsFeatureList &features ) override;
 | 
			
		||||
    bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = 0 ) override;
 | 
			
		||||
 | 
			
		||||
    //! Delete a feature from the layer (but does not commit it)
 | 
			
		||||
    bool deleteFeature( QgsFeatureId fid );
 | 
			
		||||
 | 
			
		||||
@ -142,18 +142,18 @@ QString QgsVectorLayerExporter::errorMessage() const
 | 
			
		||||
  return mErrorMessage;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool QgsVectorLayerExporter::addFeatures( QgsFeatureList &features )
 | 
			
		||||
bool QgsVectorLayerExporter::addFeatures( QgsFeatureList &features, Flags flags )
 | 
			
		||||
{
 | 
			
		||||
  QgsFeatureList::iterator fIt = features.begin();
 | 
			
		||||
  bool result = true;
 | 
			
		||||
  for ( ; fIt != features.end(); ++fIt )
 | 
			
		||||
  {
 | 
			
		||||
    result = result && addFeature( *fIt );
 | 
			
		||||
    result = result && addFeature( *fIt, flags );
 | 
			
		||||
  }
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool QgsVectorLayerExporter::addFeature( QgsFeature &feat )
 | 
			
		||||
bool QgsVectorLayerExporter::addFeature( QgsFeature &feat, Flags )
 | 
			
		||||
{
 | 
			
		||||
  QgsAttributes attrs = feat.attributes();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -133,8 +133,8 @@ class CORE_EXPORT QgsVectorLayerExporter : public QgsFeatureSink
 | 
			
		||||
     */
 | 
			
		||||
    int errorCount() const { return mErrorCount; }
 | 
			
		||||
 | 
			
		||||
    bool addFeatures( QgsFeatureList &features ) override;
 | 
			
		||||
    bool addFeature( QgsFeature &feature ) override;
 | 
			
		||||
    bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = 0 ) override;
 | 
			
		||||
    bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = 0 ) override;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Finalizes the export and closes the new created layer.
 | 
			
		||||
 | 
			
		||||
@ -897,7 +897,7 @@ bool QgsDb2Provider::changeAttributeValues( const QgsChangedAttributesMap &attr_
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool QgsDb2Provider::addFeatures( QgsFeatureList &flist )
 | 
			
		||||
bool QgsDb2Provider::addFeatures( QgsFeatureList &flist, Flags flags )
 | 
			
		||||
{
 | 
			
		||||
  QgsDebugMsg( "mGeometryColType: " + mGeometryColType );
 | 
			
		||||
  int writeCount = 0;
 | 
			
		||||
@ -1122,31 +1122,34 @@ bool QgsDb2Provider::addFeatures( QgsFeatureList &flist )
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    statement = QString( "select IDENTITY_VAL_LOCAL() AS IDENTITY "
 | 
			
		||||
                         "FROM SYSIBM.SYSDUMMY1" );
 | 
			
		||||
    if ( !( flags & QgsFeatureSink::FastInsert ) )
 | 
			
		||||
    {
 | 
			
		||||
      statement = QString( "select IDENTITY_VAL_LOCAL() AS IDENTITY "
 | 
			
		||||
                           "FROM SYSIBM.SYSDUMMY1" );
 | 
			
		||||
//    QgsDebugMsg( statement );
 | 
			
		||||
    if ( !queryFid.exec( statement ) )
 | 
			
		||||
    {
 | 
			
		||||
      QString msg = query.lastError().text();
 | 
			
		||||
      QgsDebugMsg( msg );
 | 
			
		||||
      if ( !mSkipFailures )
 | 
			
		||||
      if ( !queryFid.exec( statement ) )
 | 
			
		||||
      {
 | 
			
		||||
        pushError( msg );
 | 
			
		||||
        return false;
 | 
			
		||||
        QString msg = query.lastError().text();
 | 
			
		||||
        QgsDebugMsg( msg );
 | 
			
		||||
        if ( !mSkipFailures )
 | 
			
		||||
        {
 | 
			
		||||
          pushError( msg );
 | 
			
		||||
          return false;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ( !queryFid.next() )
 | 
			
		||||
    {
 | 
			
		||||
      QString msg = query.lastError().text();
 | 
			
		||||
      QgsDebugMsg( msg );
 | 
			
		||||
      if ( !mSkipFailures )
 | 
			
		||||
      if ( !queryFid.next() )
 | 
			
		||||
      {
 | 
			
		||||
        pushError( msg );
 | 
			
		||||
        return false;
 | 
			
		||||
        QString msg = query.lastError().text();
 | 
			
		||||
        QgsDebugMsg( msg );
 | 
			
		||||
        if ( !mSkipFailures )
 | 
			
		||||
        {
 | 
			
		||||
          pushError( msg );
 | 
			
		||||
          return false;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      it->setId( queryFid.value( 0 ).toLongLong() );
 | 
			
		||||
    }
 | 
			
		||||
    it->setId( queryFid.value( 0 ).toLongLong() );
 | 
			
		||||
    writeCount++;
 | 
			
		||||
//    QgsDebugMsg( QString( "count: %1; featureId: %2" ).arg( writeCount ).arg( queryFid.value( 0 ).toLongLong() ) );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -83,7 +83,7 @@ class QgsDb2Provider : public QgsVectorDataProvider
 | 
			
		||||
 | 
			
		||||
    virtual QgsVectorDataProvider::Capabilities capabilities() const override;
 | 
			
		||||
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &flist ) override;
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &flist, QgsFeatureSink::Flags flags = 0 ) override;
 | 
			
		||||
 | 
			
		||||
    virtual bool deleteFeatures( const QgsFeatureIds &id ) override;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -190,14 +190,14 @@ QgsFeatureIterator QgsGPXProvider::getFeatures( const QgsFeatureRequest &request
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool QgsGPXProvider::addFeatures( QgsFeatureList &flist )
 | 
			
		||||
bool QgsGPXProvider::addFeatures( QgsFeatureList &flist, Flags flags )
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
  // add all the features
 | 
			
		||||
  for ( QgsFeatureList::iterator iter = flist.begin();
 | 
			
		||||
        iter != flist.end(); ++iter )
 | 
			
		||||
  {
 | 
			
		||||
    if ( !addFeature( *iter ) )
 | 
			
		||||
    if ( !addFeature( *iter, flags ) )
 | 
			
		||||
      return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -211,7 +211,7 @@ bool QgsGPXProvider::addFeatures( QgsFeatureList &flist )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool QgsGPXProvider::addFeature( QgsFeature &f )
 | 
			
		||||
bool QgsGPXProvider::addFeature( QgsFeature &f, Flags )
 | 
			
		||||
{
 | 
			
		||||
  QByteArray wkb( f.geometry().exportToWkb() );
 | 
			
		||||
  const char *geo = wkb.constData();
 | 
			
		||||
 | 
			
		||||
@ -54,7 +54,7 @@ class QgsGPXProvider : public QgsVectorDataProvider
 | 
			
		||||
    virtual QgsWkbTypes::Type wkbType() const override;
 | 
			
		||||
    virtual long featureCount() const override;
 | 
			
		||||
    virtual QgsFields fields() const override;
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &flist ) override;
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &flist, QgsFeatureSink::Flags flags = 0 ) override;
 | 
			
		||||
    virtual bool deleteFeatures( const QgsFeatureIds &id ) override;
 | 
			
		||||
    virtual bool changeAttributeValues( const QgsChangedAttributesMap &attr_map ) override;
 | 
			
		||||
    virtual QgsVectorDataProvider::Capabilities capabilities() const override;
 | 
			
		||||
@ -75,7 +75,7 @@ class QgsGPXProvider : public QgsVectorDataProvider
 | 
			
		||||
    void changeAttributeValues( QgsGPSObject &obj,
 | 
			
		||||
                                const QgsAttributeMap &attrs );
 | 
			
		||||
 | 
			
		||||
    bool addFeature( QgsFeature &f ) override;
 | 
			
		||||
    bool addFeature( QgsFeature &f, QgsFeatureSink::Flags flags = 0 ) override;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    enum DataType
 | 
			
		||||
 | 
			
		||||
@ -818,7 +818,7 @@ bool QgsMssqlProvider::isValid() const
 | 
			
		||||
  return mValid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool QgsMssqlProvider::addFeatures( QgsFeatureList &flist )
 | 
			
		||||
bool QgsMssqlProvider::addFeatures( QgsFeatureList &flist, Flags flags )
 | 
			
		||||
{
 | 
			
		||||
  for ( QgsFeatureList::iterator it = flist.begin(); it != flist.end(); ++it )
 | 
			
		||||
  {
 | 
			
		||||
@ -1012,30 +1012,33 @@ bool QgsMssqlProvider::addFeatures( QgsFeatureList &flist )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    statement = QStringLiteral( "SELECT IDENT_CURRENT('%1.%2')" ).arg( mSchemaName, mTableName );
 | 
			
		||||
 | 
			
		||||
    if ( !query.exec( statement ) )
 | 
			
		||||
    if ( !( flags & QgsFeatureSink::FastInsert ) )
 | 
			
		||||
    {
 | 
			
		||||
      QString msg = query.lastError().text();
 | 
			
		||||
      QgsDebugMsg( msg );
 | 
			
		||||
      if ( !mSkipFailures )
 | 
			
		||||
      {
 | 
			
		||||
        pushError( msg );
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
      statement = QStringLiteral( "SELECT IDENT_CURRENT('%1.%2')" ).arg( mSchemaName, mTableName );
 | 
			
		||||
 | 
			
		||||
    if ( !query.next() )
 | 
			
		||||
    {
 | 
			
		||||
      QString msg = query.lastError().text();
 | 
			
		||||
      QgsDebugMsg( msg );
 | 
			
		||||
      if ( !mSkipFailures )
 | 
			
		||||
      if ( !query.exec( statement ) )
 | 
			
		||||
      {
 | 
			
		||||
        pushError( msg );
 | 
			
		||||
        return false;
 | 
			
		||||
        QString msg = query.lastError().text();
 | 
			
		||||
        QgsDebugMsg( msg );
 | 
			
		||||
        if ( !mSkipFailures )
 | 
			
		||||
        {
 | 
			
		||||
          pushError( msg );
 | 
			
		||||
          return false;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if ( !query.next() )
 | 
			
		||||
      {
 | 
			
		||||
        QString msg = query.lastError().text();
 | 
			
		||||
        QgsDebugMsg( msg );
 | 
			
		||||
        if ( !mSkipFailures )
 | 
			
		||||
        {
 | 
			
		||||
          pushError( msg );
 | 
			
		||||
          return false;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      it->setId( query.value( 0 ).toLongLong() );
 | 
			
		||||
    }
 | 
			
		||||
    it->setId( query.value( 0 ).toLongLong() );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return true;
 | 
			
		||||
 | 
			
		||||
@ -101,7 +101,7 @@ class QgsMssqlProvider : public QgsVectorDataProvider
 | 
			
		||||
 | 
			
		||||
    virtual bool isSaveAndLoadStyleToDatabaseSupported() const override { return true; }
 | 
			
		||||
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &flist ) override;
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &flist, QgsFeatureSink::Flags flags = 0 ) override;
 | 
			
		||||
 | 
			
		||||
    virtual bool deleteFeatures( const QgsFeatureIds &id ) override;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1228,7 +1228,7 @@ OGRGeometryH QgsOgrProvider::ConvertGeometryIfNecessary( OGRGeometryH hGeom )
 | 
			
		||||
  return OGR_G_ForceTo( hGeom, layerGeomType, nullptr );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool QgsOgrProvider::addFeaturePrivate( QgsFeature &f )
 | 
			
		||||
bool QgsOgrProvider::addFeaturePrivate( QgsFeature &f, Flags flags )
 | 
			
		||||
{
 | 
			
		||||
  bool returnValue = true;
 | 
			
		||||
  OGRFeatureDefnH fdef = OGR_L_GetLayerDefn( ogrLayer );
 | 
			
		||||
@ -1357,7 +1357,7 @@ bool QgsOgrProvider::addFeaturePrivate( QgsFeature &f )
 | 
			
		||||
    pushError( tr( "OGR error creating feature %1: %2" ).arg( f.id() ).arg( CPLGetLastErrorMsg() ) );
 | 
			
		||||
    returnValue = false;
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  else if ( !( flags & QgsFeatureSink::FastInsert ) )
 | 
			
		||||
  {
 | 
			
		||||
    QgsFeatureId id = static_cast<QgsFeatureId>( OGR_F_GetFID( feature ) );
 | 
			
		||||
    if ( id >= 0 )
 | 
			
		||||
@ -1376,7 +1376,7 @@ bool QgsOgrProvider::addFeaturePrivate( QgsFeature &f )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool QgsOgrProvider::addFeatures( QgsFeatureList &flist )
 | 
			
		||||
bool QgsOgrProvider::addFeatures( QgsFeatureList &flist, Flags flags )
 | 
			
		||||
{
 | 
			
		||||
  if ( !doInitialActionsForEdition() )
 | 
			
		||||
    return false;
 | 
			
		||||
@ -1388,7 +1388,7 @@ bool QgsOgrProvider::addFeatures( QgsFeatureList &flist )
 | 
			
		||||
  bool returnvalue = true;
 | 
			
		||||
  for ( QgsFeatureList::iterator it = flist.begin(); it != flist.end(); ++it )
 | 
			
		||||
  {
 | 
			
		||||
    if ( !addFeaturePrivate( *it ) )
 | 
			
		||||
    if ( !addFeaturePrivate( *it, flags ) )
 | 
			
		||||
    {
 | 
			
		||||
      returnvalue = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -78,7 +78,7 @@ class QgsOgrProvider : public QgsVectorDataProvider
 | 
			
		||||
    virtual QgsRectangle extent() const override;
 | 
			
		||||
    QVariant defaultValue( int fieldId ) const override;
 | 
			
		||||
    virtual void updateExtents() override;
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &flist ) override;
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &flist, QgsFeatureSink::Flags flags = 0 ) override;
 | 
			
		||||
    virtual bool deleteFeatures( const QgsFeatureIds &id ) override;
 | 
			
		||||
    virtual bool addAttributes( const QList<QgsField> &attributes ) override;
 | 
			
		||||
    virtual bool deleteAttributes( const QgsAttributeIds &attributes ) override;
 | 
			
		||||
@ -225,7 +225,7 @@ class QgsOgrProvider : public QgsVectorDataProvider
 | 
			
		||||
 | 
			
		||||
    mutable QStringList mSubLayerList;
 | 
			
		||||
 | 
			
		||||
    bool addFeaturePrivate( QgsFeature &f );
 | 
			
		||||
    bool addFeaturePrivate( QgsFeature &f, QgsFeatureSink::Flags flags );
 | 
			
		||||
    //! Deletes one feature
 | 
			
		||||
    bool deleteFeature( QgsFeatureId id );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1935,7 +1935,7 @@ QString QgsPostgresProvider::geomParam( int offset ) const
 | 
			
		||||
  return geometry;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool QgsPostgresProvider::addFeatures( QgsFeatureList &flist )
 | 
			
		||||
bool QgsPostgresProvider::addFeatures( QgsFeatureList &flist, Flags flags )
 | 
			
		||||
{
 | 
			
		||||
  if ( flist.isEmpty() )
 | 
			
		||||
    return true;
 | 
			
		||||
@ -2160,33 +2160,36 @@ bool QgsPostgresProvider::addFeatures( QgsFeatureList &flist )
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // update feature ids
 | 
			
		||||
    if ( mPrimaryKeyType == PktInt || mPrimaryKeyType == PktFidMap || mPrimaryKeyType == PktUint64 )
 | 
			
		||||
    if ( !( flags & QgsFeatureSink::FastInsert ) )
 | 
			
		||||
    {
 | 
			
		||||
      for ( QgsFeatureList::iterator features = flist.begin(); features != flist.end(); ++features )
 | 
			
		||||
      // update feature ids
 | 
			
		||||
      if ( mPrimaryKeyType == PktInt || mPrimaryKeyType == PktFidMap || mPrimaryKeyType == PktUint64 )
 | 
			
		||||
      {
 | 
			
		||||
        QgsAttributes attrs = features->attributes();
 | 
			
		||||
        for ( QgsFeatureList::iterator features = flist.begin(); features != flist.end(); ++features )
 | 
			
		||||
        {
 | 
			
		||||
          QgsAttributes attrs = features->attributes();
 | 
			
		||||
 | 
			
		||||
        if ( mPrimaryKeyType == PktUint64 )
 | 
			
		||||
        {
 | 
			
		||||
          features->setId( STRING_TO_FID( attrs.at( mPrimaryKeyAttrs.at( 0 ) ) ) );
 | 
			
		||||
        }
 | 
			
		||||
        else if ( mPrimaryKeyType == PktInt )
 | 
			
		||||
        {
 | 
			
		||||
          features->setId( PKINT2FID( STRING_TO_FID( attrs.at( mPrimaryKeyAttrs.at( 0 ) ) ) ) );
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
          QVariantList primaryKeyVals;
 | 
			
		||||
 | 
			
		||||
          Q_FOREACH ( int idx, mPrimaryKeyAttrs )
 | 
			
		||||
          if ( mPrimaryKeyType == PktUint64 )
 | 
			
		||||
          {
 | 
			
		||||
            primaryKeyVals << attrs.at( idx );
 | 
			
		||||
            features->setId( STRING_TO_FID( attrs.at( mPrimaryKeyAttrs.at( 0 ) ) ) );
 | 
			
		||||
          }
 | 
			
		||||
          else if ( mPrimaryKeyType == PktInt )
 | 
			
		||||
          {
 | 
			
		||||
            features->setId( PKINT2FID( STRING_TO_FID( attrs.at( mPrimaryKeyAttrs.at( 0 ) ) ) ) );
 | 
			
		||||
          }
 | 
			
		||||
          else
 | 
			
		||||
          {
 | 
			
		||||
            QVariantList primaryKeyVals;
 | 
			
		||||
 | 
			
		||||
          features->setId( mShared->lookupFid( primaryKeyVals ) );
 | 
			
		||||
            Q_FOREACH ( int idx, mPrimaryKeyAttrs )
 | 
			
		||||
            {
 | 
			
		||||
              primaryKeyVals << attrs.at( idx );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            features->setId( mShared->lookupFid( primaryKeyVals ) );
 | 
			
		||||
          }
 | 
			
		||||
          QgsDebugMsgLevel( QString( "new fid=%1" ).arg( features->id() ), 4 );
 | 
			
		||||
        }
 | 
			
		||||
        QgsDebugMsgLevel( QString( "new fid=%1" ).arg( features->id() ), 4 );
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -138,7 +138,7 @@ class QgsPostgresProvider : public QgsVectorDataProvider
 | 
			
		||||
    QString defaultValueClause( int fieldId ) const override;
 | 
			
		||||
    QVariant defaultValue( int fieldId ) const override;
 | 
			
		||||
    bool skipConstraintCheck( int fieldIndex, QgsFieldConstraints::Constraint constraint, const QVariant &value = QVariant() ) const override;
 | 
			
		||||
    bool addFeatures( QgsFeatureList &flist ) override;
 | 
			
		||||
    bool addFeatures( QgsFeatureList &flist, QgsFeatureSink::Flags flags = 0 ) override;
 | 
			
		||||
    bool deleteFeatures( const QgsFeatureIds &id ) override;
 | 
			
		||||
    bool truncate() override;
 | 
			
		||||
    bool addAttributes( const QList<QgsField> &attributes ) override;
 | 
			
		||||
 | 
			
		||||
@ -3829,7 +3829,7 @@ static void deleteWkbBlob( void *wkbBlob )
 | 
			
		||||
  delete[]( char * )wkbBlob;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool QgsSpatiaLiteProvider::addFeatures( QgsFeatureList &flist )
 | 
			
		||||
bool QgsSpatiaLiteProvider::addFeatures( QgsFeatureList &flist, Flags flags )
 | 
			
		||||
{
 | 
			
		||||
  sqlite3_stmt *stmt = nullptr;
 | 
			
		||||
  char *errMsg = nullptr;
 | 
			
		||||
@ -3978,7 +3978,10 @@ bool QgsSpatiaLiteProvider::addFeatures( QgsFeatureList &flist )
 | 
			
		||||
        if ( ret == SQLITE_DONE || ret == SQLITE_ROW )
 | 
			
		||||
        {
 | 
			
		||||
          // update feature id
 | 
			
		||||
          feature->setId( sqlite3_last_insert_rowid( mSqliteHandle ) );
 | 
			
		||||
          if ( !( flags & QgsFeatureSink::FastInsert ) )
 | 
			
		||||
          {
 | 
			
		||||
            feature->setId( sqlite3_last_insert_rowid( mSqliteHandle ) );
 | 
			
		||||
          }
 | 
			
		||||
          mNumberFeatures++;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
 | 
			
		||||
@ -102,7 +102,7 @@ class QgsSpatiaLiteProvider: public QgsVectorDataProvider
 | 
			
		||||
 | 
			
		||||
    bool isValid() const override;
 | 
			
		||||
    virtual bool isSaveAndLoadStyleToDatabaseSupported() const override { return true; }
 | 
			
		||||
    bool addFeatures( QgsFeatureList &flist ) override;
 | 
			
		||||
    bool addFeatures( QgsFeatureList &flist, QgsFeatureSink::Flags flags = 0 ) override;
 | 
			
		||||
    bool deleteFeatures( const QgsFeatureIds &id ) override;
 | 
			
		||||
    bool truncate() override;
 | 
			
		||||
    bool addAttributes( const QList<QgsField> &attributes ) override;
 | 
			
		||||
 | 
			
		||||
@ -779,7 +779,7 @@ QgsFeatureIterator QgsWFSProvider::getFeatures( const QgsFeatureRequest &request
 | 
			
		||||
  return QgsFeatureIterator( new QgsWFSFeatureIterator( new QgsWFSFeatureSource( this ), true, request ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool QgsWFSProvider::addFeatures( QgsFeatureList &flist )
 | 
			
		||||
bool QgsWFSProvider::addFeatures( QgsFeatureList &flist, Flags flags )
 | 
			
		||||
{
 | 
			
		||||
  //create <Transaction> xml
 | 
			
		||||
  QDomDocument transactionDoc;
 | 
			
		||||
@ -872,17 +872,20 @@ bool QgsWFSProvider::addFeatures( QgsFeatureList &flist )
 | 
			
		||||
    }
 | 
			
		||||
    mShared->serializeFeatures( serializedFeatureList );
 | 
			
		||||
 | 
			
		||||
    // And now set the feature id from the one got from the database
 | 
			
		||||
    QMap< QString, QgsFeatureId > map;
 | 
			
		||||
    for ( int idx = 0; idx < serializedFeatureList.size(); idx++ )
 | 
			
		||||
      map[ serializedFeatureList[idx].second ] = serializedFeatureList[idx].first.id();
 | 
			
		||||
 | 
			
		||||
    idIt = idList.constBegin();
 | 
			
		||||
    featureIt = flist.begin();
 | 
			
		||||
    for ( ; idIt != idList.constEnd() && featureIt != flist.end(); ++idIt, ++featureIt )
 | 
			
		||||
    if ( !( flags & QgsFeatureSink::FastInsert ) )
 | 
			
		||||
    {
 | 
			
		||||
      if ( map.find( *idIt ) != map.end() )
 | 
			
		||||
        featureIt->setId( map[*idIt] );
 | 
			
		||||
      // And now set the feature id from the one got from the database
 | 
			
		||||
      QMap< QString, QgsFeatureId > map;
 | 
			
		||||
      for ( int idx = 0; idx < serializedFeatureList.size(); idx++ )
 | 
			
		||||
        map[ serializedFeatureList[idx].second ] = serializedFeatureList[idx].first.id();
 | 
			
		||||
 | 
			
		||||
      idIt = idList.constBegin();
 | 
			
		||||
      featureIt = flist.begin();
 | 
			
		||||
      for ( ; idIt != idList.constEnd() && featureIt != flist.end(); ++idIt, ++featureIt )
 | 
			
		||||
      {
 | 
			
		||||
        if ( map.find( *idIt ) != map.end() )
 | 
			
		||||
          featureIt->setId( map[*idIt] );
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
 | 
			
		||||
@ -102,7 +102,7 @@ class QgsWFSProvider : public QgsVectorDataProvider
 | 
			
		||||
 | 
			
		||||
    //Editing operations
 | 
			
		||||
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &flist ) override;
 | 
			
		||||
    virtual bool addFeatures( QgsFeatureList &flist, QgsFeatureSink::Flags flags = 0 ) override;
 | 
			
		||||
    virtual bool deleteFeatures( const QgsFeatureIds &id ) override;
 | 
			
		||||
    virtual bool changeGeometryValues( const QgsGeometryMap &geometry_map ) override;
 | 
			
		||||
    virtual bool changeAttributeValues( const QgsChangedAttributesMap &attr_map ) override;
 | 
			
		||||
 | 
			
		||||
@ -25,6 +25,7 @@ from qgis.core import (
 | 
			
		||||
    QgsExpressionContext,
 | 
			
		||||
    QgsVectorDataProvider,
 | 
			
		||||
    QgsVectorLayerFeatureSource,
 | 
			
		||||
    QgsFeatureSink,
 | 
			
		||||
    NULL
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@ -361,6 +362,27 @@ class ProviderTestCase(FeatureSourceTestCase):
 | 
			
		||||
            # expect fail
 | 
			
		||||
            self.assertFalse(l.dataProvider().addFeatures([f1, f2]), 'Provider reported no AddFeatures capability, but returned true to addFeatures')
 | 
			
		||||
 | 
			
		||||
    def testAddFeatureFastInsert(self):
 | 
			
		||||
        if not getattr(self, 'getEditableLayer', None):
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        l = self.getEditableLayer()
 | 
			
		||||
        self.assertTrue(l.isValid())
 | 
			
		||||
 | 
			
		||||
        f1 = QgsFeature()
 | 
			
		||||
        f1.setAttributes([6, -220, NULL, 'String', '15'])
 | 
			
		||||
        f1.setGeometry(QgsGeometry.fromWkt('Point (-72.345 71.987)'))
 | 
			
		||||
 | 
			
		||||
        f2 = QgsFeature()
 | 
			
		||||
        f2.setAttributes([7, 330, 'Coconut', 'CoCoNut', '13'])
 | 
			
		||||
 | 
			
		||||
        if l.dataProvider().capabilities() & QgsVectorDataProvider.AddFeatures:
 | 
			
		||||
            # expect success
 | 
			
		||||
            result, added = l.dataProvider().addFeatures([f1, f2], QgsFeatureSink.FastInsert)
 | 
			
		||||
            self.assertTrue(result, 'Provider reported AddFeatures capability, but returned False to addFeatures')
 | 
			
		||||
            self.assertEqual(l.dataProvider().featureCount(),7)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def testAddFeaturesUpdateExtent(self):
 | 
			
		||||
        if not getattr(self, 'getEditableLayer', None):
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user