Branch data Line data Source code
1 : : /***************************************************************************
2 : : qgsogrprovider.h Data provider for ESRI shapefile format
3 : : Formerly known as qgsshapefileprovider.h
4 : : begin : Oct 29, 2003
5 : : copyright : (C) 2003 by Gary E.Sherman
6 : : email : sherman at mrcc.com
7 : : ***************************************************************************/
8 : :
9 : : /***************************************************************************
10 : : * *
11 : : * This program is free software; you can redistribute it and/or modify *
12 : : * it under the terms of the GNU General Public License as published by *
13 : : * the Free Software Foundation; either version 2 of the License, or *
14 : : * (at your option) any later version. *
15 : : * *
16 : : ***************************************************************************/
17 : :
18 : : #ifndef QGSOGRPROVIDER_H
19 : : #define QGSOGRPROVIDER_H
20 : :
21 : : #include "QTextCodec"
22 : :
23 : : #include "qgsrectangle.h"
24 : : #include "qgsvectordataprovider.h"
25 : : #include "qgsvectorfilewriter.h"
26 : : #include "qgsvectorlayerexporter.h"
27 : : #include "qgsprovidermetadata.h"
28 : : #include "qgis_sip.h"
29 : :
30 : : ///@cond PRIVATE
31 : : #define SIP_NO_FILE
32 : :
33 : : class QgsField;
34 : : class QgsVectorLayerExporter;
35 : : class QgsProviderMetadata;
36 : : class QgsOgrFeatureIterator;
37 : :
38 : : #include <gdal.h>
39 : :
40 : : class QgsOgrLayer;
41 : : class QgsOgrTransaction;
42 : :
43 : : /**
44 : : * Releases a QgsOgrLayer
45 : : */
46 : : struct QgsOgrLayerReleaser
47 : : {
48 : :
49 : : /**
50 : : * Releases a QgsOgrLayer \a layer.
51 : : */
52 : : void operator()( QgsOgrLayer *layer );
53 : :
54 : : };
55 : :
56 : : /**
57 : : * Scoped QgsOgrLayer.
58 : : */
59 : : using QgsOgrLayerUniquePtr = std::unique_ptr< QgsOgrLayer, QgsOgrLayerReleaser>;
60 : :
61 : : /**
62 : : * \class QgsOgrProvider
63 : : * \brief Data provider for OGR datasources
64 : : */
65 : : class QgsOgrProvider final: public QgsVectorDataProvider
66 : : {
67 : 325 : Q_OBJECT
68 : :
69 : : public:
70 : :
71 : : //! Convert a vector layer to a vector file
72 : : static QgsVectorLayerExporter::ExportError createEmptyLayer(
73 : : const QString &uri,
74 : : const QgsFields &fields,
75 : : QgsWkbTypes::Type wkbType,
76 : : const QgsCoordinateReferenceSystem &srs,
77 : : bool overwrite,
78 : : QMap<int, int> *oldToNewAttrIdxMap,
79 : : QString *errorMessage = nullptr,
80 : : const QMap<QString, QVariant> *options = nullptr
81 : : );
82 : :
83 : : /**
84 : : * Constructor of the vector provider
85 : : * \param uri uniform resource locator (URI) for a dataset
86 : : * \param options generic data provider options
87 : : */
88 : : explicit QgsOgrProvider( QString const &uri,
89 : : const QgsDataProvider::ProviderOptions &providerOptions,
90 : : QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags() );
91 : :
92 : : ~QgsOgrProvider() override;
93 : :
94 : : /**
95 : : * Gets the data source specification. This may be a path or database
96 : : * connection string
97 : : * \param expandAuthConfig Whether to expand any assigned authentication configuration
98 : : * \returns data source specification
99 : : * \note The default authentication configuration expansion is FALSE. This keeps credentials
100 : : * out of layer data source URIs and project files. Expansion should be specifically done
101 : : * only when needed within a provider
102 : : */
103 : : QString dataSourceUri( bool expandAuthConfig = false ) const override;
104 : :
105 : : QgsAbstractFeatureSource *featureSource() const override;
106 : :
107 : : QgsCoordinateReferenceSystem crs() const override;
108 : :
109 : : /**
110 : : * Gets the number of sublayer in the OGR datasource.
111 : : * layer_styles is not counted.
112 : : * \since QGIS 3.16
113 : : */
114 : : uint subLayerCount() const override;
115 : : QStringList subLayers() const override;
116 : : QgsLayerMetadata layerMetadata() const override;
117 : : QStringList subLayersWithoutFeatureCount() const;
118 : : QString storageType() const override;
119 : : QgsFeatureIterator getFeatures( const QgsFeatureRequest &request ) const override;
120 : : QString subsetString() const override;
121 : : bool supportsSubsetString() const override { return true; }
122 : : bool setSubsetString( const QString &theSQL, bool updateFeatureCount = true ) override;
123 : : QgsWkbTypes::Type wkbType() const override;
124 : : virtual size_t layerCount() const;
125 : : long featureCount() const override;
126 : : QgsFields fields() const override;
127 : : QgsRectangle extent() const override;
128 : : QVariant defaultValue( int fieldId ) const override;
129 : : QString defaultValueClause( int fieldIndex ) const override;
130 : : bool skipConstraintCheck( int fieldIndex, QgsFieldConstraints::Constraint constraint, const QVariant &value = QVariant() ) const override;
131 : : void updateExtents() override;
132 : : bool addFeatures( QgsFeatureList &flist, QgsFeatureSink::Flags flags = QgsFeatureSink::Flags() ) override;
133 : : bool deleteFeatures( const QgsFeatureIds &id ) override;
134 : : bool addAttributes( const QList<QgsField> &attributes ) override;
135 : : bool deleteAttributes( const QgsAttributeIds &attributes ) override;
136 : : bool renameAttributes( const QgsFieldNameMap &renamedAttributes ) override;
137 : : bool changeAttributeValues( const QgsChangedAttributesMap &attr_map ) override;
138 : : bool changeGeometryValues( const QgsGeometryMap &geometry_map ) override;
139 : : bool createSpatialIndex() override;
140 : : bool createAttributeIndex( int field ) override;
141 : : QgsVectorDataProvider::Capabilities capabilities() const override;
142 : : QgsAttributeList pkAttributeIndexes() const override { return mPrimaryKeyAttrs; }
143 : : void setEncoding( const QString &e ) override;
144 : : bool enterUpdateMode() override { return _enterUpdateMode(); }
145 : : bool leaveUpdateMode() override;
146 : : bool isSaveAndLoadStyleToDatabaseSupported() const override;
147 : : bool isDeleteStyleFromDatabaseSupported() const override;
148 : : QString fileVectorFilters() const override;
149 : : bool isValid() const override;
150 : : QVariant minimumValue( int index ) const override;
151 : : QVariant maximumValue( int index ) const override;
152 : : QSet< QVariant > uniqueValues( int index, int limit = -1 ) const override;
153 : : QStringList uniqueStringsMatching( int index, const QString &substring, int limit = -1,
154 : : QgsFeedback *feedback = nullptr ) const override;
155 : : QgsFeatureSource::SpatialIndexPresence hasSpatialIndex() const override;
156 : :
157 : : QString name() const override;
158 : : static QString providerKey();
159 : : QString description() const override;
160 : : QgsTransaction *transaction() const override;
161 : : bool doesStrictFeatureTypeCheck() const override;
162 : : QgsFeatureRenderer *createRenderer( const QVariantMap &configuration = QVariantMap() ) const override;
163 : :
164 : : //! Returns OGR geometry type
165 : : static OGRwkbGeometryType getOgrGeomType( const QString &driverName, OGRLayerH ogrLayer );
166 : :
167 : : //! Gets single flatten geometry type
168 : : static OGRwkbGeometryType ogrWkbSingleFlatten( OGRwkbGeometryType type );
169 : :
170 : 133 : QString layerName() const { return mLayerName; }
171 : :
172 : : QString filePath() const { return mFilePath; }
173 : :
174 : 133 : QString authCfg() const { return mAuthCfg; }
175 : :
176 : 133 : int layerIndex() const { return mLayerIndex; }
177 : :
178 : : QByteArray quotedIdentifier( const QByteArray &field ) const;
179 : :
180 : : protected:
181 : : //! Loads fields from input file to member attributeFields
182 : : void loadFields();
183 : :
184 : : //! Find out the number of features of the whole layer
185 : : void recalculateFeatureCount() const;
186 : :
187 : : //! Tell OGR, which fields to fetch in nextFeature/featureAtId (ie. which not to ignore)
188 : : void setRelevantFields( bool fetchGeometry, const QgsAttributeList &fetchAttributes ) const;
189 : :
190 : : //! Convert a QgsField to work with OGR
191 : : static bool convertField( QgsField &field, const QTextCodec &encoding );
192 : :
193 : : //! Clean shapefile from features which are marked as deleted
194 : : void repack();
195 : :
196 : : //! Invalidate extent and optionally force its low level recomputation
197 : : void invalidateCachedExtent( bool bForceRecomputeExtent );
198 : :
199 : : enum OpenMode
200 : : {
201 : : OpenModeInitial,
202 : : OpenModeSameAsCurrent,
203 : : OpenModeForceReadOnly,
204 : : OpenModeForceUpdate,
205 : : OpenModeForceUpdateRepackOff
206 : : };
207 : :
208 : : void open( OpenMode mode );
209 : : void close();
210 : :
211 : : bool _enterUpdateMode( bool implicit = false );
212 : :
213 : : private:
214 : : unsigned char *getGeometryPointer( OGRFeatureH fet );
215 : : QString ogrWkbGeometryTypeName( OGRwkbGeometryType type ) const;
216 : : static QString createIndexName( QString tableName, QString field );
217 : :
218 : : //! Starts a transaction if possible and return true in that case
219 : : bool startTransaction();
220 : :
221 : : //! Commits a transaction
222 : : bool commitTransaction();
223 : :
224 : : //! Rolls back a transaction
225 : : bool rollbackTransaction();
226 : :
227 : : //! Does the real job of settings the subset string and adds an argument to disable update capabilities
228 : : bool _setSubsetString( const QString &theSQL, bool updateFeatureCount = true, bool updateCapabilities = true, bool hasExistingRef = true );
229 : :
230 : : void addSubLayerDetailsToSubLayerList( int i, QgsOgrLayer *layer, bool withFeatureCount ) const;
231 : :
232 : : QStringList _subLayers( bool withFeatureCount ) const;
233 : :
234 : : QgsFields mAttributeFields;
235 : :
236 : : //! Map of field index to default value
237 : : QMap<int, QString> mDefaultValues;
238 : :
239 : : bool mFirstFieldIsFid = false;
240 : : mutable std::unique_ptr< OGREnvelope > mExtent;
241 : : bool mForceRecomputeExtent = false;
242 : :
243 : : QList<int> mPrimaryKeyAttrs;
244 : :
245 : : /**
246 : : * This member variable receives the same value as extent_
247 : : * in the method QgsOgrProvider::extent(). The purpose is to prevent a memory leak.
248 : : */
249 : : mutable QgsRectangle mExtentRect;
250 : :
251 : : /**
252 : : * Current working layer - will point to either mOgrSqlLayer or mOgrOrigLayer depending
253 : : * on whether a subset string is set
254 : : */
255 : : QgsOgrLayer *mOgrLayer = nullptr;
256 : :
257 : : //! SQL result layer, used if a subset string is set
258 : : QgsOgrLayerUniquePtr mOgrSqlLayer;
259 : :
260 : : //! Original layer (not a SQL result layer)
261 : : QgsOgrLayerUniquePtr mOgrOrigLayer;
262 : :
263 : : QgsLayerMetadata mLayerMetadata;
264 : :
265 : : //! path to filename
266 : : QString mFilePath;
267 : :
268 : : //! Authentication configuration
269 : : QString mAuthCfg;
270 : :
271 : : //! layer name
272 : : QString mLayerName;
273 : :
274 : : //! layer index
275 : : int mLayerIndex = 0;
276 : :
277 : : //! open options
278 : : QStringList mOpenOptions;
279 : :
280 : : //! was a sub layer requested?
281 : : bool mIsSubLayer = false;
282 : :
283 : : /**
284 : : * Optional geometry type for layers with multiple geometries,
285 : : * otherwise wkbUnknown. This type is always flatten (2D) and single, it means
286 : : * that 2D, 25D, single and multi types are mixed in one sublayer.
287 : : */
288 : : OGRwkbGeometryType mOgrGeometryTypeFilter = wkbUnknown;
289 : :
290 : : //! current spatial filter
291 : : QgsRectangle mFetchRect;
292 : :
293 : : //! String used to define a subset of the layer
294 : : QString mSubsetString;
295 : :
296 : : // Friendly name of the GDAL Driver that was actually used to open the layer
297 : : QString mGDALDriverName;
298 : :
299 : : //! Whether we can share the same dataset handle among different layers
300 : : bool mShareSameDatasetAmongLayers = true;
301 : :
302 : : bool mValid = false;
303 : :
304 : : OGRwkbGeometryType mOGRGeomType = wkbUnknown;
305 : :
306 : : //! Whether the next call to featureCount() should refresh the feature count
307 : : mutable bool mRefreshFeatureCount = true;
308 : :
309 : : mutable long mFeaturesCounted = QgsVectorDataProvider::Uncounted;
310 : :
311 : : mutable QStringList mSubLayerList;
312 : :
313 : : //! Converts \a value from json QVariant to QString
314 : : QString jsonStringValue( const QVariant &value ) const;
315 : :
316 : : //! The \a incrementalFeatureId will generally be -1, except for a few OGR drivers where QGIS will pass on a value when OGR doesn't set it
317 : : bool addFeaturePrivate( QgsFeature &f, QgsFeatureSink::Flags flags, QgsFeatureId incrementalFeatureId = -1 );
318 : :
319 : : //! Deletes one feature
320 : : bool deleteFeature( QgsFeatureId id );
321 : :
322 : : //! Calls OGR_L_SyncToDisk and recreates the spatial index if present
323 : : bool syncToDisc();
324 : :
325 : : friend class QgsOgrFeatureSource;
326 : :
327 : : //! Whether the file is opened in write mode
328 : : bool mWriteAccess = false;
329 : :
330 : : //! Whether the file can potentially be opened in write mode (but not necessarily currently)
331 : : bool mWriteAccessPossible = false;
332 : :
333 : : //! Whether the open mode of the datasource changes w.r.t calls to enterUpdateMode() / leaveUpdateMode()
334 : : bool mDynamicWriteAccess = false;
335 : :
336 : : bool mShapefileMayBeCorrupted = false;
337 : :
338 : : //! Converts the geometry to the layer type if necessary. Takes ownership of the passed geometry
339 : : OGRGeometryH ConvertGeometryIfNecessary( OGRGeometryH );
340 : :
341 : : int mUpdateModeStackDepth = 0;
342 : :
343 : : bool mDeferRepack = false;
344 : :
345 : : void computeCapabilities();
346 : :
347 : : QgsVectorDataProvider::Capabilities mCapabilities = QgsVectorDataProvider::Capabilities();
348 : :
349 : : bool doInitialActionsForEdition();
350 : :
351 : : bool addAttributeOGRLevel( const QgsField &field, bool &ignoreErrorOut );
352 : :
353 : : QgsOgrTransaction *mTransaction = nullptr;
354 : :
355 : : void setTransaction( QgsTransaction *transaction ) override;
356 : :
357 : : /**
358 : : * Invalidates and reopens the file and resets the feature count
359 : : * E.g. in case a shapefile is replaced, the old file will be closed
360 : : * and the new file will be opened.
361 : : */
362 : : void reloadProviderData() override;
363 : : };
364 : :
365 : : class QgsOgrDataset;
366 : :
367 : : /**
368 : : * Scoped QgsOgrDataset.
369 : : */
370 : : using QgsOgrDatasetSharedPtr = std::shared_ptr< QgsOgrDataset>;
371 : :
372 : :
373 : : /**
374 : : * \class QgsOgrProviderUtils
375 : : * \brief Utility class with static methods
376 : : */
377 : : class CORE_EXPORT QgsOgrProviderUtils
378 : : {
379 : : friend class QgsOgrDataset;
380 : : friend class QgsOgrLayer;
381 : :
382 : : //! Identifies a dataset by name, updateMode and options
383 : 1247 : class DatasetIdentification
384 : : {
385 : : QString toString() const;
386 : :
387 : : public:
388 : : QString dsName;
389 : 500 : bool updateMode = false;
390 : : QStringList options;
391 : 500 : DatasetIdentification() = default;
392 : :
393 : : bool operator< ( const DatasetIdentification &other ) const;
394 : : };
395 : :
396 : : //! GDAL dataset objects and layers in use in it
397 : 247 : class DatasetWithLayers
398 : : {
399 : : public:
400 : : #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
401 : : QMutex mutex;
402 : : #else
403 : : QRecursiveMutex mutex;
404 : : #endif
405 : 250 : GDALDatasetH hDS = nullptr;
406 : : QMap<QString, QgsOgrLayer *> setLayers;
407 : 250 : int refCount = 0;
408 : 250 : bool canBeShared = true;
409 : :
410 : 250 : DatasetWithLayers()
411 : : #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
412 : : : mutex( QMutex::Recursive )
413 : : #endif
414 : 250 : {}
415 : : };
416 : :
417 : : //! Map dataset identification to a list of corresponding DatasetWithLayers*
418 : : static QMap< DatasetIdentification, QList<DatasetWithLayers *> > sMapSharedDS;
419 : :
420 : : static bool canUseOpenedDatasets( const QString &dsName );
421 : :
422 : : static void releaseInternal( const DatasetIdentification &ident,
423 : : DatasetWithLayers *ds,
424 : : bool removeFromDatasetList );
425 : :
426 : : static DatasetWithLayers *createDatasetWithLayers(
427 : : const QString &dsName,
428 : : bool updateMode,
429 : : const QStringList &options,
430 : : const QString &layerName,
431 : : const DatasetIdentification &ident,
432 : : QgsOgrLayerUniquePtr &layer,
433 : : QString &errCause );
434 : : public:
435 : :
436 : : static QString fileVectorFilters();
437 : : static QString databaseDrivers();
438 : : static QString protocolDrivers();
439 : : static QString directoryDrivers();
440 : : static QStringList fileExtensions();
441 : : static QStringList directoryExtensions();
442 : : static QStringList wildcards();
443 : :
444 : : /**
445 : : * Creates an empty data source
446 : : * \param uri location to store the file(s)
447 : : * \param format data format (e.g. "ESRI Shapefile")
448 : : * \param vectortype point/line/polygon or multitypes
449 : : * \param attributes a list of name/type pairs for the initial attributes
450 : : * \return TRUE in case of success
451 : : */
452 : : static bool createEmptyDataSource( const QString &uri,
453 : : const QString &format,
454 : : const QString &encoding,
455 : : QgsWkbTypes::Type vectortype,
456 : : const QList< QPair<QString, QString> > &attributes,
457 : : const QgsCoordinateReferenceSystem &srs,
458 : : QString &errorMessage );
459 : :
460 : : static bool deleteLayer( const QString &uri, QString &errCause );
461 : :
462 : : //! Inject credentials into the dsName (if any)
463 : : static QString expandAuthConfig( const QString &dsName );
464 : :
465 : : static void setRelevantFields( OGRLayerH ogrLayer, int fieldCount,
466 : : bool fetchGeometry,
467 : : const QgsAttributeList &fetchAttributes,
468 : : bool firstAttrIsFid,
469 : : const QString &subsetString );
470 : :
471 : : /**
472 : : * Sets a subset string for an OGR \a layer.
473 : : * Might return either layer, or a new OGR SQL result layer
474 : : */
475 : : static OGRLayerH setSubsetString( OGRLayerH layer, GDALDatasetH ds, QTextCodec *encoding, const QString &subsetString );
476 : : static QByteArray quotedIdentifier( QByteArray field, const QString &driverName );
477 : :
478 : : /**
479 : : * Quote a value for placement in a SQL string.
480 : : */
481 : : static QString quotedValue( const QVariant &value );
482 : :
483 : : //! Wrapper for GDALOpenEx() that does a few lower level actions. Should be strictly paired with GDALCloseWrapper()
484 : : static GDALDatasetH GDALOpenWrapper( const char *pszPath, bool bUpdate, char **papszOpenOptionsIn, GDALDriverH *phDriver );
485 : :
486 : : //! Wrapper for GDALClose()
487 : : static void GDALCloseWrapper( GDALDatasetH mhDS );
488 : :
489 : : //! Return a QgsOgrDataset wrapping an already opened GDALDataset. Typical use: by QgsOgrTransaction
490 : : static QgsOgrDatasetSharedPtr getAlreadyOpenedDataset( const QString &dsName );
491 : :
492 : : //! Open a layer given by name, potentially reusing an existing GDALDatasetH if it doesn't already use that layer.
493 : : static QgsOgrLayerUniquePtr getLayer( const QString &dsName,
494 : : const QString &layerName,
495 : : QString &errCause );
496 : :
497 : :
498 : : //! Open a layer given by name, potentially reusing an existing GDALDatasetH if it has been opened with the same (updateMode, options) tuple and doesn't already use that layer.
499 : : static QgsOgrLayerUniquePtr getLayer( const QString &dsName,
500 : : bool updateMode,
501 : : const QStringList &options,
502 : : const QString &layerName,
503 : : QString &errCause,
504 : : bool checkModificationDateAgainstCache );
505 : :
506 : : //! Open a layer given by index, potentially reusing an existing GDALDatasetH if it doesn't already use that layer.
507 : : static QgsOgrLayerUniquePtr getLayer( const QString &dsName,
508 : : int layerIndex,
509 : : QString &errCause );
510 : :
511 : : //! Open a layer given by index, potentially reusing an existing GDALDatasetH if it has been opened with the same (updateMode, options) tuple and doesn't already use that layer.
512 : : static QgsOgrLayerUniquePtr getLayer( const QString &dsName,
513 : : bool updateMode,
514 : : const QStringList &options,
515 : : int layerIndex,
516 : : QString &errCause,
517 : : bool checkModificationDateAgainstCache );
518 : :
519 : : //! Returns a QgsOgrLayer* with a SQL result layer
520 : : static QgsOgrLayerUniquePtr getSqlLayer( QgsOgrLayer *baseLayer, OGRLayerH hSqlLayer, const QString &sql );
521 : :
522 : : //! Release a QgsOgrLayer*
523 : : static void release( QgsOgrLayer *&layer );
524 : :
525 : : //! Release a QgsOgrDataset*
526 : : static void releaseDataset( QgsOgrDataset *&ds );
527 : :
528 : : //! Make sure that the existing pool of opened datasets on dsName is not accessible for new getLayer() attempts
529 : : static void invalidateCachedDatasets( const QString &dsName );
530 : :
531 : : //! Returns the string to provide to QgsOgrConnPool::instance() methods
532 : : static QString connectionPoolId( const QString &dataSourceURI, bool datasetSharedAmongLayers );
533 : :
534 : : //! Invalidate the cached last modified date of a dataset
535 : : static void invalidateCachedLastModifiedDate( const QString &dsName );
536 : :
537 : : //! Converts a QGIS WKB type to the corresponding OGR wkb type
538 : : static OGRwkbGeometryType ogrTypeFromQgisType( QgsWkbTypes::Type type );
539 : :
540 : : //! Converts a OGR WKB type to the corresponding QGIS wkb type
541 : : static QgsWkbTypes::Type qgisTypeFromOgrType( OGRwkbGeometryType type );
542 : :
543 : : //! Whether a driver can share the same dataset handle among different layers
544 : : static bool canDriverShareSameDatasetAmongLayers( const QString &driverName );
545 : :
546 : : //! Whether a driver can share the same dataset handle among different layers
547 : : static bool canDriverShareSameDatasetAmongLayers( const QString &driverName,
548 : : bool updateMode,
549 : : const QString &dsName );
550 : : };
551 : :
552 : :
553 : : /**
554 : : * \class QgsOgrDataset
555 : : * \brief Wrap a GDALDatasetH object in a thread-safe way
556 : : */
557 : : class QgsOgrDataset
558 : : {
559 : : friend class QgsOgrProviderUtils;
560 : : QgsOgrProviderUtils::DatasetIdentification mIdent;
561 : : QgsOgrProviderUtils::DatasetWithLayers *mDs;
562 : :
563 : 0 : QgsOgrDataset() = default;
564 : 0 : ~QgsOgrDataset() = default;
565 : :
566 : : public:
567 : :
568 : : static QgsOgrDatasetSharedPtr create( const QgsOgrProviderUtils::DatasetIdentification &ident,
569 : : QgsOgrProviderUtils::DatasetWithLayers *ds );
570 : : #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
571 : : QMutex &mutex() { return mDs->mutex; }
572 : : #else
573 : 0 : QRecursiveMutex &mutex() { return mDs->mutex; }
574 : : #endif
575 : :
576 : : bool executeSQLNoReturn( const QString &sql );
577 : :
578 : : OGRLayerH getLayerFromNameOrIndex( const QString &layerName, int layerIndex );
579 : :
580 : : void releaseResultSet( OGRLayerH hSqlLayer );
581 : : };
582 : :
583 : :
584 : : /**
585 : : * \class QgsOgrFeatureDefn
586 : : * \brief Wrap a OGRFieldDefnH object in a thread-safe way
587 : : */
588 : : class QgsOgrFeatureDefn
589 : : {
590 : : friend class QgsOgrLayer;
591 : :
592 : 250 : OGRFeatureDefnH hDefn = nullptr;
593 : 250 : QgsOgrLayer *layer = nullptr;
594 : :
595 : 250 : QgsOgrFeatureDefn() = default;
596 : : ~QgsOgrFeatureDefn() = default;
597 : :
598 : : OGRFeatureDefnH get();
599 : : #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
600 : : QMutex &mutex();
601 : : #else
602 : : QRecursiveMutex &mutex();
603 : : #endif
604 : :
605 : : public:
606 : :
607 : : //! Wrapper of OGR_FD_GetFieldCount
608 : : int GetFieldCount();
609 : :
610 : : //! Wrapper of OGR_FD_GetFieldDefn
611 : : OGRFieldDefnH GetFieldDefn( int );
612 : :
613 : : //! Wrapper of OGR_FD_GetFieldIndex
614 : : int GetFieldIndex( const QByteArray & );
615 : :
616 : : //! Wrapper of OGR_FD_GetGeomFieldCount
617 : : int GetGeomFieldCount();
618 : :
619 : : //! Wrapper of OGR_FD_GetGeomFieldDefn
620 : : OGRGeomFieldDefnH GetGeomFieldDefn( int idx );
621 : :
622 : : //! Wrapper of OGR_FD_GetGeomType
623 : : OGRwkbGeometryType GetGeomType();
624 : :
625 : : //! Wrapper of OGR_F_Create
626 : : OGRFeatureH CreateFeature();
627 : : };
628 : :
629 : :
630 : : /**
631 : : * \class QgsOgrLayer
632 : : * \brief Wrap a OGRLayerH object in a thread-safe way
633 : : */
634 : : class QgsOgrLayer
635 : : {
636 : : friend class QgsOgrFeatureDefn;
637 : : friend class QgsOgrProviderUtils;
638 : :
639 : : QgsOgrProviderUtils::DatasetIdentification ident;
640 : : bool isSqlLayer = false;
641 : : QString layerName;
642 : : QString sql; // not really used. Just set at QgsOgrLayer::CreateForLayer() time
643 : : QgsOgrProviderUtils::DatasetWithLayers *ds = nullptr;
644 : : OGRLayerH hLayer = nullptr;
645 : : QgsOgrFeatureDefn oFDefn;
646 : :
647 : : QgsOgrLayer();
648 : 247 : ~QgsOgrLayer() = default;
649 : :
650 : : static QgsOgrLayerUniquePtr CreateForLayer(
651 : : const QgsOgrProviderUtils::DatasetIdentification &ident,
652 : : const QString &layerName,
653 : : QgsOgrProviderUtils::DatasetWithLayers *ds,
654 : : OGRLayerH hLayer );
655 : :
656 : : static QgsOgrLayerUniquePtr CreateForSql(
657 : : const QgsOgrProviderUtils::DatasetIdentification &ident,
658 : : const QString &sql,
659 : : QgsOgrProviderUtils::DatasetWithLayers *ds,
660 : : OGRLayerH hLayer );
661 : :
662 : : #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
663 : : QMutex &mutex() { return ds->mutex; }
664 : : #else
665 : 890 : QRecursiveMutex &mutex() { return ds->mutex; }
666 : : #endif
667 : :
668 : : public:
669 : :
670 : : //! Returns GDALDriverH object for current dataset
671 : : GDALDriverH driver();
672 : :
673 : : //! Returns driver name for current dataset
674 : : QString driverName();
675 : :
676 : : //! Returns current dataset name
677 : 0 : const QString &datasetName() const { return ident.dsName; }
678 : :
679 : : //! Returns dataset open mode
680 : 0 : bool updateMode() const { return ident.updateMode; }
681 : :
682 : : //! Returns dataset open options
683 : 0 : const QStringList &options() const { return ident.options; }
684 : :
685 : : //! Returns layer name
686 : : QByteArray name();
687 : :
688 : : //! Wrapper of OGR_L_GetLayerCount
689 : : int GetLayerCount();
690 : :
691 : : //! Wrapper of OGR_L_GetLayerCount
692 : : QByteArray GetFIDColumn();
693 : :
694 : : //! Wrapper of OGR_L_GetLayerCount
695 : : OGRSpatialReferenceH GetSpatialRef();
696 : :
697 : : //! Wrapper of OGR_L_GetLayerCount
698 : : void ResetReading();
699 : :
700 : : //! Wrapper of OGR_L_GetLayerCount
701 : : OGRFeatureH GetNextFeature();
702 : :
703 : : //! Wrapper of OGR_L_GetLayerCount
704 : : OGRFeatureH GetFeature( GIntBig fid );
705 : :
706 : : //! Wrapper of OGR_L_GetLayerCount
707 : : QgsOgrFeatureDefn &GetLayerDefn();
708 : :
709 : : //! Wrapper of OGR_L_GetLayerCount
710 : : GIntBig GetFeatureCount( bool force = false );
711 : :
712 : : //! Return an approximate feature count
713 : : GIntBig GetApproxFeatureCount();
714 : :
715 : : //! Wrapper of OGR_L_GetLayerCount
716 : : OGRErr GetExtent( OGREnvelope *psExtent, bool bForce );
717 : :
718 : : //! Wrapper of OGR_L_GetLayerCount
719 : : OGRErr CreateFeature( OGRFeatureH hFeature );
720 : :
721 : : //! Wrapper of OGR_L_GetLayerCount
722 : : OGRErr SetFeature( OGRFeatureH hFeature );
723 : :
724 : : //! Wrapper of OGR_L_GetLayerCount
725 : : OGRErr DeleteFeature( GIntBig fid );
726 : :
727 : : //! Wrapper of OGR_L_GetLayerCount
728 : : OGRErr CreateField( OGRFieldDefnH hFieldDefn, bool bStrict );
729 : :
730 : : //! Wrapper of OGR_L_GetLayerCount
731 : : OGRErr DeleteField( int iField );
732 : :
733 : : //! Wrapper of OGR_L_GetLayerCount
734 : : OGRErr AlterFieldDefn( int iField, OGRFieldDefnH hNewFieldDefn, int flags );
735 : :
736 : : //! Wrapper of OGR_L_GetLayerCount
737 : : int TestCapability( const char * );
738 : :
739 : : //! Wrapper of OGR_L_GetLayerCount
740 : : OGRErr StartTransaction();
741 : :
742 : : //! Wrapper of OGR_L_GetLayerCount
743 : : OGRErr CommitTransaction();
744 : :
745 : : //! Wrapper of OGR_L_GetLayerCount
746 : : OGRErr RollbackTransaction();
747 : :
748 : : //! Wrapper of OGR_L_GetLayerCount
749 : : OGRErr SyncToDisk();
750 : :
751 : : //! Wrapper of OGR_L_GetLayerCount
752 : : OGRGeometryH GetSpatialFilter();
753 : :
754 : : //! Wrapper of OGR_L_GetLayerCount
755 : : void SetSpatialFilter( OGRGeometryH );
756 : :
757 : : #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
758 : : //! Returns native GDALDatasetH object with the mutex to lock when using it
759 : : GDALDatasetH getDatasetHandleAndMutex( QMutex *&mutex );
760 : :
761 : : //! Returns native OGRLayerH object with the mutex to lock when using it
762 : : OGRLayerH getHandleAndMutex( QMutex *&mutex );
763 : : #else
764 : : //! Returns native GDALDatasetH object with the mutex to lock when using it
765 : : GDALDatasetH getDatasetHandleAndMutex( QRecursiveMutex *&mutex );
766 : :
767 : : //! Returns native OGRLayerH object with the mutex to lock when using it
768 : : OGRLayerH getHandleAndMutex( QRecursiveMutex *&mutex );
769 : : #endif
770 : :
771 : :
772 : : //! Wrapper of GDALDatasetReleaseResultSet( GDALDatasetExecuteSQL( ... ) )
773 : : void ExecuteSQLNoReturn( const QByteArray &sql );
774 : :
775 : : //! Wrapper of GDALDatasetExecuteSQL().
776 : : QgsOgrLayerUniquePtr ExecuteSQL( const QByteArray &sql );
777 : :
778 : : // Wrapper of GDALGetMetadataItem()
779 : : QString GetMetadataItem( const QString &key, const QString &domain = QString() );
780 : : };
781 : :
782 : : /**
783 : : * Entry point for registration of the OGR data provider
784 : : * \since QGIS 3.10
785 : : */
786 : 338 : class QgsOgrProviderMetadata final: public QgsProviderMetadata
787 : : {
788 : : public:
789 : :
790 : : QgsOgrProviderMetadata();
791 : :
792 : : void initProvider() override;
793 : : void cleanupProvider() override;
794 : : QList< QgsDataItemProvider * > dataItemProviders() const override;
795 : : QgsOgrProvider *createProvider( const QString &uri, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags() ) override;
796 : : QVariantMap decodeUri( const QString &uri ) const override;
797 : : QString encodeUri( const QVariantMap &parts ) const override;
798 : : QString filters( FilterType type ) override;
799 : : ProviderCapabilities providerCapabilities() const override;
800 : : bool uriIsBlocklisted( const QString &uri ) const override;
801 : : QgsVectorLayerExporter::ExportError createEmptyLayer(
802 : : const QString &uri,
803 : : const QgsFields &fields,
804 : : QgsWkbTypes::Type wkbType,
805 : : const QgsCoordinateReferenceSystem &srs,
806 : : bool overwrite,
807 : : QMap<int, int> &oldToNewAttrIdxMap,
808 : : QString &errorMessage,
809 : : const QMap<QString, QVariant> *options ) override;
810 : :
811 : : // -----
812 : : bool saveStyle( const QString &uri, const QString &qmlStyle, const QString &sldStyle,
813 : : const QString &styleName, const QString &styleDescription,
814 : : const QString &uiFileContent, bool useAsDefault, QString &errCause ) override;
815 : : bool deleteStyleById( const QString &uri, QString styleId, QString &errCause ) override;
816 : : QString loadStyle( const QString &uri, QString &errCause ) override;
817 : : int listStyles( const QString &uri, QStringList &ids, QStringList &names,
818 : : QStringList &descriptions, QString &errCause ) override;
819 : : QString getStyleById( const QString &uri, QString styleId, QString &errCause ) override;
820 : :
821 : : // -----
822 : : QgsTransaction *createTransaction( const QString &connString ) override;
823 : :
824 : : // QgsProviderMetadata interface
825 : : public:
826 : : QMap<QString, QgsAbstractProviderConnection *> connections( bool cached ) override;
827 : : QgsAbstractProviderConnection *createConnection( const QString &name ) override;
828 : : void deleteConnection( const QString &name ) override;
829 : : void saveConnection( const QgsAbstractProviderConnection *connection, const QString &name ) override;
830 : :
831 : : protected:
832 : :
833 : : QgsAbstractProviderConnection *createConnection( const QString &uri, const QVariantMap &configuration ) override;
834 : :
835 : : };
836 : :
837 : : ///@endcond
838 : : // clazy:excludeall=qstring-allocations
839 : : #endif // QGSOGRPROVIDER_H
|