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 : : QMutex mutex;
401 : 250 : GDALDatasetH hDS = nullptr;
402 : : QMap<QString, QgsOgrLayer *> setLayers;
403 : 250 : int refCount = 0;
404 : 250 : bool canBeShared = true;
405 : :
406 : 250 : DatasetWithLayers(): mutex( QMutex::Recursive ) {}
407 : : };
408 : :
409 : : //! Map dataset identification to a list of corresponding DatasetWithLayers*
410 : : static QMap< DatasetIdentification, QList<DatasetWithLayers *> > sMapSharedDS;
411 : :
412 : : static bool canUseOpenedDatasets( const QString &dsName );
413 : :
414 : : static void releaseInternal( const DatasetIdentification &ident,
415 : : DatasetWithLayers *ds,
416 : : bool removeFromDatasetList );
417 : :
418 : : static DatasetWithLayers *createDatasetWithLayers(
419 : : const QString &dsName,
420 : : bool updateMode,
421 : : const QStringList &options,
422 : : const QString &layerName,
423 : : const DatasetIdentification &ident,
424 : : QgsOgrLayerUniquePtr &layer,
425 : : QString &errCause );
426 : : public:
427 : :
428 : : static QString fileVectorFilters();
429 : : static QString databaseDrivers();
430 : : static QString protocolDrivers();
431 : : static QString directoryDrivers();
432 : : static QStringList fileExtensions();
433 : : static QStringList directoryExtensions();
434 : : static QStringList wildcards();
435 : :
436 : : /**
437 : : * Creates an empty data source
438 : : * \param uri location to store the file(s)
439 : : * \param format data format (e.g. "ESRI Shapefile")
440 : : * \param vectortype point/line/polygon or multitypes
441 : : * \param attributes a list of name/type pairs for the initial attributes
442 : : * \return TRUE in case of success
443 : : */
444 : : static bool createEmptyDataSource( const QString &uri,
445 : : const QString &format,
446 : : const QString &encoding,
447 : : QgsWkbTypes::Type vectortype,
448 : : const QList< QPair<QString, QString> > &attributes,
449 : : const QgsCoordinateReferenceSystem &srs,
450 : : QString &errorMessage );
451 : :
452 : : static bool deleteLayer( const QString &uri, QString &errCause );
453 : :
454 : : //! Inject credentials into the dsName (if any)
455 : : static QString expandAuthConfig( const QString &dsName );
456 : :
457 : : static void setRelevantFields( OGRLayerH ogrLayer, int fieldCount,
458 : : bool fetchGeometry,
459 : : const QgsAttributeList &fetchAttributes,
460 : : bool firstAttrIsFid,
461 : : const QString &subsetString );
462 : :
463 : : /**
464 : : * Sets a subset string for an OGR \a layer.
465 : : * Might return either layer, or a new OGR SQL result layer
466 : : */
467 : : static OGRLayerH setSubsetString( OGRLayerH layer, GDALDatasetH ds, QTextCodec *encoding, const QString &subsetString );
468 : : static QByteArray quotedIdentifier( QByteArray field, const QString &driverName );
469 : :
470 : : /**
471 : : * Quote a value for placement in a SQL string.
472 : : */
473 : : static QString quotedValue( const QVariant &value );
474 : :
475 : : //! Wrapper for GDALOpenEx() that does a few lower level actions. Should be strictly paired with GDALCloseWrapper()
476 : : static GDALDatasetH GDALOpenWrapper( const char *pszPath, bool bUpdate, char **papszOpenOptionsIn, GDALDriverH *phDriver );
477 : :
478 : : //! Wrapper for GDALClose()
479 : : static void GDALCloseWrapper( GDALDatasetH mhDS );
480 : :
481 : : //! Return a QgsOgrDataset wrapping an already opened GDALDataset. Typical use: by QgsOgrTransaction
482 : : static QgsOgrDatasetSharedPtr getAlreadyOpenedDataset( const QString &dsName );
483 : :
484 : : //! Open a layer given by name, potentially reusing an existing GDALDatasetH if it doesn't already use that layer.
485 : : static QgsOgrLayerUniquePtr getLayer( const QString &dsName,
486 : : const QString &layerName,
487 : : QString &errCause );
488 : :
489 : :
490 : : //! 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.
491 : : static QgsOgrLayerUniquePtr getLayer( const QString &dsName,
492 : : bool updateMode,
493 : : const QStringList &options,
494 : : const QString &layerName,
495 : : QString &errCause,
496 : : bool checkModificationDateAgainstCache );
497 : :
498 : : //! Open a layer given by index, potentially reusing an existing GDALDatasetH if it doesn't already use that layer.
499 : : static QgsOgrLayerUniquePtr getLayer( const QString &dsName,
500 : : int layerIndex,
501 : : QString &errCause );
502 : :
503 : : //! 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.
504 : : static QgsOgrLayerUniquePtr getLayer( const QString &dsName,
505 : : bool updateMode,
506 : : const QStringList &options,
507 : : int layerIndex,
508 : : QString &errCause,
509 : : bool checkModificationDateAgainstCache );
510 : :
511 : : //! Returns a QgsOgrLayer* with a SQL result layer
512 : : static QgsOgrLayerUniquePtr getSqlLayer( QgsOgrLayer *baseLayer, OGRLayerH hSqlLayer, const QString &sql );
513 : :
514 : : //! Release a QgsOgrLayer*
515 : : static void release( QgsOgrLayer *&layer );
516 : :
517 : : //! Release a QgsOgrDataset*
518 : : static void releaseDataset( QgsOgrDataset *&ds );
519 : :
520 : : //! Make sure that the existing pool of opened datasets on dsName is not accessible for new getLayer() attempts
521 : : static void invalidateCachedDatasets( const QString &dsName );
522 : :
523 : : //! Returns the string to provide to QgsOgrConnPool::instance() methods
524 : : static QString connectionPoolId( const QString &dataSourceURI, bool datasetSharedAmongLayers );
525 : :
526 : : //! Invalidate the cached last modified date of a dataset
527 : : static void invalidateCachedLastModifiedDate( const QString &dsName );
528 : :
529 : : //! Converts a QGIS WKB type to the corresponding OGR wkb type
530 : : static OGRwkbGeometryType ogrTypeFromQgisType( QgsWkbTypes::Type type );
531 : :
532 : : //! Converts a OGR WKB type to the corresponding QGIS wkb type
533 : : static QgsWkbTypes::Type qgisTypeFromOgrType( OGRwkbGeometryType type );
534 : :
535 : : //! Whether a driver can share the same dataset handle among different layers
536 : : static bool canDriverShareSameDatasetAmongLayers( const QString &driverName );
537 : :
538 : : //! Whether a driver can share the same dataset handle among different layers
539 : : static bool canDriverShareSameDatasetAmongLayers( const QString &driverName,
540 : : bool updateMode,
541 : : const QString &dsName );
542 : : };
543 : :
544 : :
545 : : /**
546 : : * \class QgsOgrDataset
547 : : * \brief Wrap a GDALDatasetH object in a thread-safe way
548 : : */
549 : : class QgsOgrDataset
550 : : {
551 : : friend class QgsOgrProviderUtils;
552 : : QgsOgrProviderUtils::DatasetIdentification mIdent;
553 : : QgsOgrProviderUtils::DatasetWithLayers *mDs;
554 : :
555 : 0 : QgsOgrDataset() = default;
556 : 0 : ~QgsOgrDataset() = default;
557 : :
558 : : public:
559 : :
560 : : static QgsOgrDatasetSharedPtr create( const QgsOgrProviderUtils::DatasetIdentification &ident,
561 : : QgsOgrProviderUtils::DatasetWithLayers *ds );
562 : :
563 : 0 : QMutex &mutex() { return mDs->mutex; }
564 : :
565 : : bool executeSQLNoReturn( const QString &sql );
566 : :
567 : : OGRLayerH getLayerFromNameOrIndex( const QString &layerName, int layerIndex );
568 : :
569 : : void releaseResultSet( OGRLayerH hSqlLayer );
570 : : };
571 : :
572 : :
573 : : /**
574 : : * \class QgsOgrFeatureDefn
575 : : * \brief Wrap a OGRFieldDefnH object in a thread-safe way
576 : : */
577 : : class QgsOgrFeatureDefn
578 : : {
579 : : friend class QgsOgrLayer;
580 : :
581 : 250 : OGRFeatureDefnH hDefn = nullptr;
582 : 250 : QgsOgrLayer *layer = nullptr;
583 : :
584 : 250 : QgsOgrFeatureDefn() = default;
585 : : ~QgsOgrFeatureDefn() = default;
586 : :
587 : : OGRFeatureDefnH get();
588 : : QMutex &mutex();
589 : :
590 : : public:
591 : :
592 : : //! Wrapper of OGR_FD_GetFieldCount
593 : : int GetFieldCount();
594 : :
595 : : //! Wrapper of OGR_FD_GetFieldDefn
596 : : OGRFieldDefnH GetFieldDefn( int );
597 : :
598 : : //! Wrapper of OGR_FD_GetFieldIndex
599 : : int GetFieldIndex( const QByteArray & );
600 : :
601 : : //! Wrapper of OGR_FD_GetGeomFieldCount
602 : : int GetGeomFieldCount();
603 : :
604 : : //! Wrapper of OGR_FD_GetGeomFieldDefn
605 : : OGRGeomFieldDefnH GetGeomFieldDefn( int idx );
606 : :
607 : : //! Wrapper of OGR_FD_GetGeomType
608 : : OGRwkbGeometryType GetGeomType();
609 : :
610 : : //! Wrapper of OGR_F_Create
611 : : OGRFeatureH CreateFeature();
612 : : };
613 : :
614 : :
615 : : /**
616 : : * \class QgsOgrLayer
617 : : * \brief Wrap a OGRLayerH object in a thread-safe way
618 : : */
619 : : class QgsOgrLayer
620 : : {
621 : : friend class QgsOgrFeatureDefn;
622 : : friend class QgsOgrProviderUtils;
623 : :
624 : : QgsOgrProviderUtils::DatasetIdentification ident;
625 : : bool isSqlLayer = false;
626 : : QString layerName;
627 : : QString sql; // not really used. Just set at QgsOgrLayer::CreateForLayer() time
628 : : QgsOgrProviderUtils::DatasetWithLayers *ds = nullptr;
629 : : OGRLayerH hLayer = nullptr;
630 : : QgsOgrFeatureDefn oFDefn;
631 : :
632 : : QgsOgrLayer();
633 : 247 : ~QgsOgrLayer() = default;
634 : :
635 : : static QgsOgrLayerUniquePtr CreateForLayer(
636 : : const QgsOgrProviderUtils::DatasetIdentification &ident,
637 : : const QString &layerName,
638 : : QgsOgrProviderUtils::DatasetWithLayers *ds,
639 : : OGRLayerH hLayer );
640 : :
641 : : static QgsOgrLayerUniquePtr CreateForSql(
642 : : const QgsOgrProviderUtils::DatasetIdentification &ident,
643 : : const QString &sql,
644 : : QgsOgrProviderUtils::DatasetWithLayers *ds,
645 : : OGRLayerH hLayer );
646 : :
647 : 890 : QMutex &mutex() { return ds->mutex; }
648 : :
649 : : public:
650 : :
651 : : //! Returns GDALDriverH object for current dataset
652 : : GDALDriverH driver();
653 : :
654 : : //! Returns driver name for current dataset
655 : : QString driverName();
656 : :
657 : : //! Returns current dataset name
658 : 0 : const QString &datasetName() const { return ident.dsName; }
659 : :
660 : : //! Returns dataset open mode
661 : 0 : bool updateMode() const { return ident.updateMode; }
662 : :
663 : : //! Returns dataset open options
664 : 0 : const QStringList &options() const { return ident.options; }
665 : :
666 : : //! Returns layer name
667 : : QByteArray name();
668 : :
669 : : //! Wrapper of OGR_L_GetLayerCount
670 : : int GetLayerCount();
671 : :
672 : : //! Wrapper of OGR_L_GetLayerCount
673 : : QByteArray GetFIDColumn();
674 : :
675 : : //! Wrapper of OGR_L_GetLayerCount
676 : : OGRSpatialReferenceH GetSpatialRef();
677 : :
678 : : //! Wrapper of OGR_L_GetLayerCount
679 : : void ResetReading();
680 : :
681 : : //! Wrapper of OGR_L_GetLayerCount
682 : : OGRFeatureH GetNextFeature();
683 : :
684 : : //! Wrapper of OGR_L_GetLayerCount
685 : : OGRFeatureH GetFeature( GIntBig fid );
686 : :
687 : : //! Wrapper of OGR_L_GetLayerCount
688 : : QgsOgrFeatureDefn &GetLayerDefn();
689 : :
690 : : //! Wrapper of OGR_L_GetLayerCount
691 : : GIntBig GetFeatureCount( bool force = false );
692 : :
693 : : //! Return an approximate feature count
694 : : GIntBig GetApproxFeatureCount();
695 : :
696 : : //! Wrapper of OGR_L_GetLayerCount
697 : : OGRErr GetExtent( OGREnvelope *psExtent, bool bForce );
698 : :
699 : : //! Wrapper of OGR_L_GetLayerCount
700 : : OGRErr CreateFeature( OGRFeatureH hFeature );
701 : :
702 : : //! Wrapper of OGR_L_GetLayerCount
703 : : OGRErr SetFeature( OGRFeatureH hFeature );
704 : :
705 : : //! Wrapper of OGR_L_GetLayerCount
706 : : OGRErr DeleteFeature( GIntBig fid );
707 : :
708 : : //! Wrapper of OGR_L_GetLayerCount
709 : : OGRErr CreateField( OGRFieldDefnH hFieldDefn, bool bStrict );
710 : :
711 : : //! Wrapper of OGR_L_GetLayerCount
712 : : OGRErr DeleteField( int iField );
713 : :
714 : : //! Wrapper of OGR_L_GetLayerCount
715 : : OGRErr AlterFieldDefn( int iField, OGRFieldDefnH hNewFieldDefn, int flags );
716 : :
717 : : //! Wrapper of OGR_L_GetLayerCount
718 : : int TestCapability( const char * );
719 : :
720 : : //! Wrapper of OGR_L_GetLayerCount
721 : : OGRErr StartTransaction();
722 : :
723 : : //! Wrapper of OGR_L_GetLayerCount
724 : : OGRErr CommitTransaction();
725 : :
726 : : //! Wrapper of OGR_L_GetLayerCount
727 : : OGRErr RollbackTransaction();
728 : :
729 : : //! Wrapper of OGR_L_GetLayerCount
730 : : OGRErr SyncToDisk();
731 : :
732 : : //! Wrapper of OGR_L_GetLayerCount
733 : : OGRGeometryH GetSpatialFilter();
734 : :
735 : : //! Wrapper of OGR_L_GetLayerCount
736 : : void SetSpatialFilter( OGRGeometryH );
737 : :
738 : : //! Returns native GDALDatasetH object with the mutex to lock when using it
739 : : GDALDatasetH getDatasetHandleAndMutex( QMutex *&mutex );
740 : :
741 : : //! Returns native OGRLayerH object with the mutex to lock when using it
742 : : OGRLayerH getHandleAndMutex( QMutex *&mutex );
743 : :
744 : : //! Wrapper of GDALDatasetReleaseResultSet( GDALDatasetExecuteSQL( ... ) )
745 : : void ExecuteSQLNoReturn( const QByteArray &sql );
746 : :
747 : : //! Wrapper of GDALDatasetExecuteSQL().
748 : : QgsOgrLayerUniquePtr ExecuteSQL( const QByteArray &sql );
749 : :
750 : : // Wrapper of GDALGetMetadataItem()
751 : : QString GetMetadataItem( const QString &key, const QString &domain = QString() );
752 : : };
753 : :
754 : : /**
755 : : * Entry point for registration of the OGR data provider
756 : : * \since QGIS 3.10
757 : : */
758 : 338 : class QgsOgrProviderMetadata final: public QgsProviderMetadata
759 : : {
760 : : public:
761 : :
762 : : QgsOgrProviderMetadata();
763 : :
764 : : void initProvider() override;
765 : : void cleanupProvider() override;
766 : : QList< QgsDataItemProvider * > dataItemProviders() const override;
767 : : QgsOgrProvider *createProvider( const QString &uri, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags() ) override;
768 : : QVariantMap decodeUri( const QString &uri ) const override;
769 : : QString encodeUri( const QVariantMap &parts ) const override;
770 : : QString filters( FilterType type ) override;
771 : : ProviderCapabilities providerCapabilities() const override;
772 : : bool uriIsBlocklisted( const QString &uri ) const override;
773 : : QgsVectorLayerExporter::ExportError createEmptyLayer(
774 : : const QString &uri,
775 : : const QgsFields &fields,
776 : : QgsWkbTypes::Type wkbType,
777 : : const QgsCoordinateReferenceSystem &srs,
778 : : bool overwrite,
779 : : QMap<int, int> &oldToNewAttrIdxMap,
780 : : QString &errorMessage,
781 : : const QMap<QString, QVariant> *options ) override;
782 : :
783 : : // -----
784 : : bool saveStyle( const QString &uri, const QString &qmlStyle, const QString &sldStyle,
785 : : const QString &styleName, const QString &styleDescription,
786 : : const QString &uiFileContent, bool useAsDefault, QString &errCause ) override;
787 : : bool deleteStyleById( const QString &uri, QString styleId, QString &errCause ) override;
788 : : QString loadStyle( const QString &uri, QString &errCause ) override;
789 : : int listStyles( const QString &uri, QStringList &ids, QStringList &names,
790 : : QStringList &descriptions, QString &errCause ) override;
791 : : QString getStyleById( const QString &uri, QString styleId, QString &errCause ) override;
792 : :
793 : : // -----
794 : : QgsTransaction *createTransaction( const QString &connString ) override;
795 : :
796 : : // QgsProviderMetadata interface
797 : : public:
798 : : QMap<QString, QgsAbstractProviderConnection *> connections( bool cached ) override;
799 : : QgsAbstractProviderConnection *createConnection( const QString &name ) override;
800 : : void deleteConnection( const QString &name ) override;
801 : : void saveConnection( const QgsAbstractProviderConnection *connection, const QString &name ) override;
802 : :
803 : : protected:
804 : :
805 : : QgsAbstractProviderConnection *createConnection( const QString &uri, const QVariantMap &configuration ) override;
806 : :
807 : : };
808 : :
809 : : ///@endcond
810 : : // clazy:excludeall=qstring-allocations
811 : : #endif // QGSOGRPROVIDER_H
|