QGIS API Documentation  3.9.0-Master (d9ef585e47)
qgsauxiliarystorage.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsauxiliarystorage.cpp - description
3  -------------------
4  begin : Aug 28, 2017
5  copyright : (C) 2017 by Paul Blottiere
6  email : [email protected]
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 #include "qgsauxiliarystorage.h"
19 #include "qgslogger.h"
20 #include "qgsspatialiteutils.h"
21 #include "qgsproject.h"
22 #include "qgsvectorlayerlabeling.h"
23 #include "qgsdiagramrenderer.h"
24 #include "qgsmemoryproviderutils.h"
25 #include "qgssymbollayer.h"
26 
27 #include <sqlite3.h>
28 #include <QFile>
29 
30 const QString AS_JOINFIELD = "ASPK";
31 const QString AS_EXTENSION = "qgd";
32 const QString AS_JOINPREFIX = "auxiliary_storage_";
33 
34 const QVector<QgsPalLayerSettings::Property> palHiddenProperties
35 {
60 };
61 
62 //
63 // QgsAuxiliaryLayer
64 //
65 
66 QgsAuxiliaryLayer::QgsAuxiliaryLayer( const QString &pkField, const QString &filename, const QString &table, QgsVectorLayer *vlayer )
67  : QgsVectorLayer( QStringLiteral( "%1|layername=%2" ).arg( filename, table ),
68  QStringLiteral( "%1_auxiliarystorage" ).arg( table ), QStringLiteral( "ogr" ) )
69  , mFileName( filename )
70  , mTable( table )
71  , mLayer( vlayer )
72 {
73  // init join info
74  mJoinInfo.setPrefix( AS_JOINPREFIX );
75  mJoinInfo.setJoinLayer( this );
76  mJoinInfo.setJoinFieldName( AS_JOINFIELD );
77  mJoinInfo.setTargetFieldName( pkField );
78  mJoinInfo.setEditable( true );
79  mJoinInfo.setUpsertOnEdit( true );
80  mJoinInfo.setCascadedDelete( true );
81  mJoinInfo.setJoinFieldNamesBlackList( QStringList() << QStringLiteral( "rowid" ) ); // introduced by ogr provider
82 }
83 
85 {
87  return new QgsAuxiliaryLayer( mJoinInfo.targetFieldName(), mFileName, target->id(), target );
88 }
89 
91 {
92  bool rc = deleteFeatures( allFeatureIds() );
93  commitChanges();
94  startEditing();
95  return rc;
96 }
97 
99 {
100  QgsVectorLayer *layer = QgsMemoryProviderUtils::createMemoryLayer( QStringLiteral( "auxiliary_layer" ), fields(), mLayer->wkbType(), mLayer->crs() );
101 
102  QString pkField = mJoinInfo.targetFieldName();
103  QgsFeature joinFeature;
104  QgsFeature targetFeature;
106 
107  layer->startEditing();
108  while ( it.nextFeature( joinFeature ) )
109  {
110  QString filter = QgsExpression::createFieldEqualityExpression( pkField, joinFeature.attribute( AS_JOINFIELD ) );
111 
112  QgsFeatureRequest request;
113  request.setFilterExpression( filter );
114 
115  mLayer->getFeatures( request ).nextFeature( targetFeature );
116 
117  if ( targetFeature.isValid() )
118  {
119  QgsFeature newFeature( joinFeature );
120  newFeature.setGeometry( targetFeature.geometry() );
121  layer->addFeature( newFeature );
122  }
123  }
124  layer->commitChanges();
125 
126  return layer;
127 }
128 
130 {
131  return mJoinInfo;
132 }
133 
134 bool QgsAuxiliaryLayer::exists( const QgsPropertyDefinition &definition ) const
135 {
136  return ( indexOfPropertyDefinition( definition ) >= 0 );
137 }
138 
140 {
141  if ( ( definition.name().isEmpty() && definition.comment().isEmpty() ) || exists( definition ) )
142  return false;
143 
144  const QgsField af = createAuxiliaryField( definition );
145  const bool rc = addAttribute( af );
146  updateFields();
147  mLayer->updateFields();
148 
149  if ( rc )
150  {
151  int auxIndex = indexOfPropertyDefinition( definition );
152  int index = mLayer->fields().indexOf( nameFromProperty( definition, true ) );
153 
154  if ( index >= 0 && auxIndex >= 0 )
155  {
156  if ( isHiddenProperty( auxIndex ) )
157  {
158  // update editor widget
159  QgsEditorWidgetSetup setup = QgsEditorWidgetSetup( QStringLiteral( "Hidden" ), QVariantMap() );
160  setEditorWidgetSetup( auxIndex, setup );
161 
162  // column is hidden
163  QgsAttributeTableConfig attrCfg = mLayer->attributeTableConfig();
164  attrCfg.update( mLayer->fields() );
165  QVector<QgsAttributeTableConfig::ColumnConfig> columns = attrCfg.columns();
166  QVector<QgsAttributeTableConfig::ColumnConfig>::iterator it;
167 
168  for ( it = columns.begin(); it != columns.end(); ++it )
169  {
170  if ( it->name.compare( mLayer->fields().field( index ).name() ) == 0 )
171  it->hidden = true;
172  }
173 
174  attrCfg.setColumns( columns );
175  mLayer->setAttributeTableConfig( attrCfg );
176  }
177  else if ( definition.standardTemplate() == QgsPropertyDefinition::ColorNoAlpha
179  {
180  QgsEditorWidgetSetup setup = QgsEditorWidgetSetup( QStringLiteral( "Color" ), QVariantMap() );
181  setEditorWidgetSetup( auxIndex, setup );
182  }
183 
184  mLayer->setEditorWidgetSetup( index, editorWidgetSetup( auxIndex ) );
185  }
186  }
187 
188  return rc;
189 }
190 
192 {
193  QgsFields afields;
194 
195  for ( int i = 2; i < fields().count(); i++ ) // ignore rowid and PK field
196  afields.append( createAuxiliaryField( fields().field( i ) ) );
197 
198  return afields;
199 }
200 
202 {
204  bool rc = commitChanges();
205  startEditing();
206  return rc;
207 }
208 
210 {
211  bool rc = false;
212 
213  if ( isEditable() )
214  {
215  rc = commitChanges();
216  }
217 
218  startEditing();
219 
220  return rc;
221 }
222 
224 {
225  int index = -1;
226 
227  if ( layer && layer->labeling() && layer->auxiliaryLayer() )
228  {
229  // property definition are identical whatever the provider id
230  const QgsPropertyDefinition def = layer->labeling()->settings().propertyDefinitions()[property];
231  const QString fieldName = nameFromProperty( def, true );
232 
233  layer->auxiliaryLayer()->addAuxiliaryField( def );
234 
235  if ( layer->auxiliaryLayer()->indexOfPropertyDefinition( def ) >= 0 )
236  {
237  const QgsProperty prop = QgsProperty::fromField( fieldName );
238 
239  const QStringList subProviderIds = layer->labeling()->subProviders();
240  for ( const QString &providerId : subProviderIds )
241  {
242  QgsPalLayerSettings *settings = new QgsPalLayerSettings( layer->labeling()->settings( providerId ) );
243 
245  c.setProperty( property, prop );
246  settings->setDataDefinedProperties( c );
247 
248  layer->labeling()->setSettings( settings, providerId );
249  }
250  }
251 
252  index = layer->fields().lookupField( fieldName );
253  }
254 
255  return index;
256 }
257 
259 {
260  int index = -1;
261 
262  if ( layer && layer->diagramLayerSettings() && layer->auxiliaryLayer() )
263  {
264  const QgsPropertyDefinition def = layer->diagramLayerSettings()->propertyDefinitions()[property];
265 
266  if ( layer->auxiliaryLayer()->addAuxiliaryField( def ) )
267  {
268  const QString fieldName = nameFromProperty( def, true );
269  const QgsProperty prop = QgsProperty::fromField( fieldName );
270 
271  QgsDiagramLayerSettings settings( *layer->diagramLayerSettings() );
272 
273  QgsPropertyCollection c = settings.dataDefinedProperties();
274  c.setProperty( property, prop );
275  settings.setDataDefinedProperties( c );
276 
277  layer->setDiagramLayerSettings( settings );
278  index = layer->fields().lookupField( fieldName );
279  }
280  }
281 
282  return index;
283 }
284 
285 bool QgsAuxiliaryLayer::isHiddenProperty( int index ) const
286 {
287  bool hidden = false;
289 
290  if ( def.origin().compare( QLatin1String( "labeling" ) ) == 0 )
291  {
293  {
294  const QString propName = QgsPalLayerSettings::propertyDefinitions()[ p ].name();
295  if ( propName.compare( def.name() ) == 0 )
296  {
297  hidden = true;
298  break;
299  }
300  }
301  }
302 
303  return hidden;
304 }
305 
307 {
308  int p = -1;
310 
311  if ( aDef.origin().compare( QLatin1String( "labeling" ) ) == 0 )
312  {
314  QgsPropertiesDefinition::const_iterator it = defs.constBegin();
315  for ( ; it != defs.constEnd(); ++it )
316  {
317  if ( it->name().compare( aDef.name(), Qt::CaseInsensitive ) == 0 )
318  {
319  p = it.key();
320  break;
321  }
322  }
323  }
324  else if ( aDef.origin().compare( QLatin1String( "symbol" ) ) == 0 )
325  {
327  QgsPropertiesDefinition::const_iterator it = defs.constBegin();
328  for ( ; it != defs.constEnd(); ++it )
329  {
330  if ( it->name().compare( aDef.name(), Qt::CaseInsensitive ) == 0 )
331  {
332  p = it.key();
333  break;
334  }
335  }
336  }
337  else if ( aDef.origin().compare( QLatin1String( "diagram" ) ) == 0 )
338  {
340  QgsPropertiesDefinition::const_iterator it = defs.constBegin();
341  for ( ; it != defs.constEnd(); ++it )
342  {
343  if ( it->name().compare( aDef.name(), Qt::CaseInsensitive ) == 0 )
344  {
345  p = it.key();
346  break;
347  }
348  }
349  }
350 
351  return p;
352 }
353 
355 {
356  return propertyDefinitionFromField( fields().field( index ) );
357 }
358 
360 {
361  return fields().indexOf( nameFromProperty( def ) );
362 }
363 
365 {
366  QString fieldName = def.origin();
367 
368  if ( !def.name().isEmpty() )
369  fieldName = QStringLiteral( "%1_%2" ).arg( fieldName, def.name().toLower() );
370 
371  if ( !def.comment().isEmpty() )
372  fieldName = QStringLiteral( "%1_%2" ).arg( fieldName, def.comment() );
373 
374  if ( joined )
375  fieldName = QStringLiteral( "%1%2" ).arg( AS_JOINPREFIX, fieldName );
376 
377  return fieldName;
378 }
379 
381 {
382  QgsField afield;
383 
384  if ( !def.name().isEmpty() || !def.comment().isEmpty() )
385  {
386  QVariant::Type type = QVariant::Invalid;
387  QString typeName;
388  int len( 0 ), precision( 0 );
389  switch ( def.dataType() )
390  {
392  type = QVariant::String;
393  len = 50;
394  typeName = QStringLiteral( "String" );
395  break;
397  type = QVariant::Double;
398  len = 0;
399  precision = 0;
400  typeName = QStringLiteral( "Real" );
401  break;
403  type = QVariant::Int; // sqlite does not have a bool type
404  typeName = QStringLiteral( "Integer" );
405  break;
406  }
407 
408  afield.setType( type );
409  afield.setName( nameFromProperty( def ) );
410  afield.setTypeName( typeName );
411  afield.setLength( len );
412  afield.setPrecision( precision );
413  }
414 
415  return afield;
416 }
417 
419 {
421  const QStringList parts = f.name().split( '_' );
422 
423  if ( parts.size() <= 1 )
424  return def;
425 
426  const QString origin = parts[0];
427  const QString propertyName = parts[1];
428 
429  if ( origin.compare( QLatin1String( "labeling" ), Qt::CaseInsensitive ) == 0 )
430  {
432  for ( auto it = props.constBegin(); it != props.constEnd(); ++it )
433  {
434  if ( it.value().name().compare( propertyName, Qt::CaseInsensitive ) == 0 )
435  {
436  def = it.value();
437  if ( parts.size() >= 3 )
438  def.setComment( parts.mid( 2 ).join( '_' ) );
439  break;
440  }
441  }
442  }
443  else if ( origin.compare( QLatin1String( "symbol" ), Qt::CaseInsensitive ) == 0 )
444  {
446  for ( auto it = props.constBegin(); it != props.constEnd(); ++it )
447  {
448  if ( it.value().name().compare( propertyName, Qt::CaseInsensitive ) == 0 )
449  {
450  def = it.value();
451  if ( parts.size() >= 3 )
452  def.setComment( parts.mid( 2 ).join( '_' ) );
453  break;
454  }
455  }
456  }
457  else if ( origin.compare( QLatin1String( "diagram" ), Qt::CaseInsensitive ) == 0 )
458  {
460  for ( auto it = props.constBegin(); it != props.constEnd(); ++it )
461  {
462  if ( it.value().name().compare( propertyName, Qt::CaseInsensitive ) == 0 )
463  {
464  def = it.value();
465  if ( parts.size() >= 3 )
466  def.setComment( parts.mid( 2 ).join( '_' ) );
467  break;
468  }
469  }
470  }
471  else
472  {
473  def.setOrigin( origin );
474  def.setName( propertyName );
475  switch ( f.type() )
476  {
477  case QVariant::Double:
479  break;
480 
481  case QVariant::Bool:
483  break;
484 
485  case QVariant::String:
486  default:
488  break;
489  }
490 
491  if ( parts.size() >= 3 )
492  def.setComment( parts.mid( 2 ).join( '_' ) );
493  }
494 
495  return def;
496 }
497 
499 {
501  QgsField afield;
502 
503  if ( !def.name().isEmpty() || !def.comment().isEmpty() )
504  {
505  afield = createAuxiliaryField( def );
506  afield.setTypeName( field.typeName() );
507  }
508 
509  return afield;
510 }
511 
512 //
513 // QgsAuxiliaryStorage
514 //
515 
517  : mCopy( copy )
518 {
519  initTmpFileName();
520 
521  if ( !project.absoluteFilePath().isEmpty() )
522  {
523  mFileName = filenameForProject( project );
524  }
525 
526  open( mFileName );
527 }
528 
529 QgsAuxiliaryStorage::QgsAuxiliaryStorage( const QString &filename, bool copy )
530  : mFileName( filename )
531  , mCopy( copy )
532 {
533  initTmpFileName();
534 
535  open( filename );
536 }
537 
539 {
540  QFile::remove( mTmpFileName );
541 }
542 
544 {
545  return mValid;
546 }
547 
549 {
550  return mFileName;
551 }
552 
554 {
555  if ( mFileName.isEmpty() )
556  {
557  // only a saveAs is available on a new database
558  return false;
559  }
560  else if ( mCopy )
561  {
562  if ( QFile::exists( mFileName ) )
563  QFile::remove( mFileName );
564 
565  return QFile::copy( mTmpFileName, mFileName );
566  }
567  else
568  {
569  // if the file is not empty the copy mode is not activated, then we're
570  // directly working on the database since the beginning (no savepoints
571  // /rollback for now)
572  return true;
573  }
574 }
575 
577 {
578  QgsAuxiliaryLayer *alayer = nullptr;
579 
580  if ( mValid && layer )
581  {
582  const QString table( layer->id() );
584  database = openDB( currentFileName() );
585 
586  if ( !tableExists( table, database.get() ) )
587  {
588  if ( !createTable( field.typeName(), table, database.get() ) )
589  {
590  return alayer;
591  }
592  }
593 
594  alayer = new QgsAuxiliaryLayer( field.name(), currentFileName(), table, layer );
595  alayer->startEditing();
596  }
597 
598  return alayer;
599 }
600 
602 {
603  bool rc = false;
604  QgsDataSourceUri uri = parseOgrUri( ogrUri );
605 
606  if ( !uri.database().isEmpty() && !uri.table().isEmpty() )
607  {
609  database = openDB( uri.database() );
610 
611  if ( database )
612  {
613  QString sql = QStringLiteral( "DROP TABLE %1" ).arg( uri.table() );
614  rc = exec( sql, database.get() );
615 
616  sql = QStringLiteral( "VACUUM" );
617  rc = exec( sql, database.get() );
618  }
619  }
620 
621  return rc;
622 }
623 
624 bool QgsAuxiliaryStorage::duplicateTable( const QgsDataSourceUri &ogrUri, const QString &newTable )
625 {
626  QgsDataSourceUri uri = parseOgrUri( ogrUri );
627  bool rc = false;
628 
629  if ( !uri.table().isEmpty() && !uri.database().isEmpty() )
630  {
632  database = openDB( uri.database() );
633 
634  if ( database )
635  {
636  QString sql = QStringLiteral( "CREATE TABLE %1 AS SELECT * FROM %2" ).arg( newTable, uri.table() );
637  rc = exec( sql, database.get() );
638  }
639  }
640 
641  return rc;
642 }
643 
645 {
646  return mErrorString;
647 }
648 
649 bool QgsAuxiliaryStorage::saveAs( const QString &filename )
650 {
651  mErrorString.clear();
652 
653  QFile dest( filename );
654  if ( dest.exists() && !dest.remove() )
655  {
656  mErrorString = dest.errorString();
657  return false;
658  }
659 
660  QFile origin( currentFileName() );
661  if ( !origin.copy( filename ) )
662  {
663  mErrorString = origin.errorString();
664  return false;
665  }
666 
667  return true;
668 }
669 
671 {
672  return saveAs( filenameForProject( project ) );
673 }
674 
676 {
677  return AS_EXTENSION;
678 }
679 
681 {
682  const QFileInfo fileinfo( filenameForProject( project ) );
683  return fileinfo.exists() && fileinfo.isFile();
684 }
685 
686 bool QgsAuxiliaryStorage::exec( const QString &sql, sqlite3 *handler )
687 {
688  bool rc = false;
689 
690  if ( handler )
691  {
692  const int err = sqlite3_exec( handler, sql.toStdString().c_str(), nullptr, nullptr, nullptr );
693 
694  if ( err == SQLITE_OK )
695  rc = true;
696  else
697  debugMsg( sql, handler );
698  }
699 
700  return rc;
701 }
702 
703 void QgsAuxiliaryStorage::debugMsg( const QString &sql, sqlite3 *handler )
704 {
705 #ifdef QGISDEBUG
706  const QString err = QString::fromUtf8( sqlite3_errmsg( handler ) );
707  const QString msg = QObject::tr( "Unable to execute" );
708  const QString errMsg = QObject::tr( "%1 '%2': %3" ).arg( msg, sql, err );
709  QgsDebugMsg( errMsg );
710 #else
711  Q_UNUSED( sql )
712  Q_UNUSED( handler )
713 #endif
714 }
715 
716 bool QgsAuxiliaryStorage::createTable( const QString &type, const QString &table, sqlite3 *handler )
717 {
718  const QString sql = QStringLiteral( "CREATE TABLE IF NOT EXISTS '%1' ( '%2' %3 )" ).arg( table, AS_JOINFIELD, type );
719 
720  if ( !exec( sql, handler ) )
721  return false;
722 
723  return true;
724 }
725 
726 spatialite_database_unique_ptr QgsAuxiliaryStorage::createDB( const QString &filename )
727 {
729 
730  int rc;
731  rc = database.open_v2( filename, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr );
732  if ( rc )
733  {
734  debugMsg( QStringLiteral( "sqlite3_open_v2" ), database.get() );
735  }
736  else
737  // activating Foreign Key constraints
738  exec( QStringLiteral( "PRAGMA foreign_keys = 1" ), database.get() );
739 
740  return database;
741 }
742 
743 spatialite_database_unique_ptr QgsAuxiliaryStorage::openDB( const QString &filename )
744 {
746  int rc = database.open_v2( filename, SQLITE_OPEN_READWRITE, nullptr );
747 
748  if ( rc )
749  {
750  debugMsg( QStringLiteral( "sqlite3_open_v2" ), database.get() );
751  }
752 
753  return database;
754 }
755 
756 bool QgsAuxiliaryStorage::tableExists( const QString &table, sqlite3 *handler )
757 {
758  const QString sql = QStringLiteral( "SELECT 1 FROM sqlite_master WHERE type='table' AND name='%1'" ).arg( table );
759  int rows = 0;
760  int columns = 0;
761  char **results = nullptr;
762  const int rc = sqlite3_get_table( handler, sql.toStdString().c_str(), &results, &rows, &columns, nullptr );
763  if ( rc != SQLITE_OK )
764  {
765  debugMsg( sql, handler );
766  return false;
767  }
768 
769  sqlite3_free_table( results );
770  if ( rows >= 1 )
771  return true;
772 
773  return false;
774 }
775 
776 spatialite_database_unique_ptr QgsAuxiliaryStorage::open( const QString &filename )
777 {
779 
780  if ( filename.isEmpty() )
781  {
782  if ( ( database = createDB( currentFileName() ) ) )
783  mValid = true;
784  }
785  else if ( QFile::exists( filename ) )
786  {
787  if ( mCopy )
788  QFile::copy( filename, mTmpFileName );
789 
790  if ( ( database = openDB( currentFileName() ) ) )
791  mValid = true;
792  }
793  else
794  {
795  if ( ( database = createDB( currentFileName() ) ) )
796  mValid = true;
797  }
798 
799  return database;
800 }
801 
802 spatialite_database_unique_ptr QgsAuxiliaryStorage::open( const QgsProject &project )
803 {
804  return open( filenameForProject( project ) );
805 }
806 
807 QString QgsAuxiliaryStorage::filenameForProject( const QgsProject &project )
808 {
809  const QFileInfo info( project.absoluteFilePath() );
810  const QString path = info.path() + QDir::separator() + info.baseName();
811  return path + '.' + QgsAuxiliaryStorage::extension();
812 }
813 
814 void QgsAuxiliaryStorage::initTmpFileName()
815 {
816  QTemporaryFile tmpFile;
817  tmpFile.open();
818  tmpFile.close();
819  mTmpFileName = tmpFile.fileName();
820 }
821 
823 {
824  if ( mCopy || mFileName.isEmpty() )
825  return mTmpFileName;
826  else
827  return mFileName;
828 }
829 
830 QgsDataSourceUri QgsAuxiliaryStorage::parseOgrUri( const QgsDataSourceUri &uri )
831 {
832  QgsDataSourceUri newUri;
833 
834  // parsing for ogr style uri :
835  // " filePath|layername='tableName' table="" sql="
836  QStringList uriParts = uri.uri().split( '|' );
837  if ( uriParts.count() < 2 )
838  return newUri;
839 
840  const QString databasePath = uriParts[0].replace( ' ', QString() );
841 
842  const QString table = uriParts[1];
843  QStringList tableParts = table.split( ' ' );
844 
845  if ( tableParts.count() < 1 )
846  return newUri;
847 
848  const QString tableName = tableParts[0].replace( QStringLiteral( "layername=" ), QString() );
849 
850  newUri.setDataSource( QString(), tableName, QString() );
851  newUri.setDatabase( databasePath );
852 
853  return newUri;
854 }
void setProperty(int key, const QgsProperty &property)
Adds a property to the collection and takes ownership of it.
int lookupField(const QString &fieldName) const
Looks up field&#39;s index from the field name.
Definition: qgsfields.cpp:324
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:183
void updateFields()
Will regenerate the fields property of this layer by obtaining all fields from the dataProvider...
void setJoinLayer(QgsVectorLayer *layer)
Sets weak reference to the joined layer.
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the labeling property definitions.
Wrapper for iterator of features from vector data provider or vector layer.
static QgsField createAuxiliaryField(const QgsPropertyDefinition &definition)
Creates a new auxiliary field from a property definition.
int precision
int open_v2(const QString &path, int flags, const char *zVfs)
Opens the database at the specified file path.
QString targetFieldName() const
Returns name of the field of our layer that will be used for join.
void setDiagramLayerSettings(const QgsDiagramLayerSettings &s)
QString table() const
Returns the table name stored in the URI.
void update(const QgsFields &fields)
Update the configuration with the given fields.
Property
Data definable properties.
bool isValid() const
Returns the status of the auxiliary storage currently defined.
QgsMapLayerType type() const
Returns the type of the layer.
QString name
Definition: qgsfield.h:58
bool save()
Commits changes and starts editing then.
QgsPropertyDefinition propertyDefinitionFromIndex(int index) const
Returns the property definition for the underlying field index.
bool exists(const QgsPropertyDefinition &definition) const
Returns true if the property is stored in the layer already, false otherwise.
int propertyFromIndex(int index) const
Returns the underlying property key for the field index.
void setEditable(bool enabled)
Sets whether the form of the target layer allows editing joined fields.
QgsWkbTypes::Type wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
void setPrecision(int precision)
Set the field precision.
Definition: qgsfield.cpp:165
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
Class allowing to manage the auxiliary storage for a vector layer.
bool commitChanges()
Attempts to commit to the underlying data provider any buffered changes made since the last to call t...
int indexOfPropertyDefinition(const QgsPropertyDefinition &definition) const
Returns the index of the auxiliary field for a specific property definition.
const QString AS_JOINFIELD
bool startEditing()
Makes the layer editable.
virtual void setSettings(QgsPalLayerSettings *settings, const QString &providerId=QString())=0
Set pal settings for a specific provider (takes ownership).
static QgsProperty fromField(const QString &fieldName, bool isActive=true)
Returns a new FieldBasedProperty created from the specified field name.
bool deleteFeatures(const QgsFeatureIds &fids)
Deletes a set of features from the layer (but does not commit it)
X-coordinate data defined label position.
void setJoinFieldName(const QString &fieldName)
Sets name of the field of joined layer that will be used for join.
Min scale (deprecated, for old project compatibility only)
Container of fields for a vector layer.
Definition: qgsfields.h:42
void setName(const QString &name)
Set the field name.
Definition: qgsfield.cpp:141
const QString AS_EXTENSION
Color with alpha channel.
Definition: qgsproperty.h:64
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
QString currentFileName() const
Returns the path of the current database used.
QgsVectorLayer * toSpatialLayer() const
An auxiliary layer is not spatial.
void setName(const QString &name)
Sets the name of the property.
Definition: qgsproperty.h:143
int count() const
Returns number of items.
Definition: qgsfields.cpp:133
static QString extension()
Returns the extension used for auxiliary databases.
virtual QStringList subProviders() const
Gets list of sub-providers within the layer&#39;s labeling.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
static int createProperty(QgsPalLayerSettings::Property property, QgsVectorLayer *vlayer)
Creates if necessary a new auxiliary field for a PAL property and activates this property in settings...
void setLength(int len)
Set the field length.
Definition: qgsfield.cpp:161
bool isEditable() const FINAL
Returns true if the provider is in editing mode.
bool save() const
Saves the current database.
Property
Data definable properties.
void setUpsertOnEdit(bool enabled)
Sets whether a feature created on the target layer has to impact the joined layer by creating a new f...
void setEditorWidgetSetup(int index, const QgsEditorWidgetSetup &setup)
The editor widget setup defines which QgsFieldFormatter and editor widget will be used for the field ...
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
QString id() const
Returns the layer&#39;s unique ID, which is used to access this layer from QgsProject.
DataType dataType() const
Returns the allowable field/value data type for the property.
Definition: qgsproperty.h:187
QgsFields fields() const FINAL
Returns the list of fields of this layer.
Unique pointer for spatialite databases, which automatically closes the database when the pointer goe...
const QVector< QgsPalLayerSettings::Property > palHiddenProperties
QString fileName() const
Returns the target filename of the database.
virtual QgsPalLayerSettings settings(const QString &providerId=QString()) const =0
Gets associated label settings.
void setDataDefinedProperties(const QgsPropertyCollection &collection)
Sets the label&#39;s property collection, used for data defined overrides.
Property requires a boolean value.
Definition: qgsproperty.h:105
QString typeName() const
Gets the field type.
Definition: qgsfield.cpp:105
void setTypeName(const QString &typeName)
Set the field type.
Definition: qgsfield.cpp:156
const QString & typeName
Defines left outer join from our vector layer to some other vector layer.
virtual bool deleteAttribute(int attr)
Deletes an attribute field (but does not commit it).
const QString AS_JOINPREFIX
virtual ~QgsAuxiliaryStorage()
Destructor.
Horizontal alignment for data defined label position (Left, Center, Right)
Property requires a numeric value.
Definition: qgsproperty.h:98
This class wraps a request for features to a vector layer (or directly its vector data provider)...
QgsVectorLayerJoinInfo joinInfo() const
Returns information to use for joining with primary key and so on.
bool append(const QgsField &field, FieldOrigin origin=OriginProvider, int originIndex=-1)
Appends a field. The field must have unique name, otherwise it is rejected (returns false) ...
Definition: qgsfields.cpp:59
Encapsulates a QGIS project, including sets of map layers and their styles, layouts, annotations, canvases, etc.
Definition: qgsproject.h:89
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:48
bool clear()
Deletes all features from the layer.
QgsAuxiliaryLayer(const QString &pkField, const QString &filename, const QString &table, QgsVectorLayer *vlayer)
Constructor.
const QgsAbstractVectorLayerLabeling * labeling() const
Access to const labeling configuration.
A store for object properties.
Definition: qgsproperty.h:229
void setTargetFieldName(const QString &fieldName)
Sets name of the field of our layer that will be used for join.
static QString createFieldEqualityExpression(const QString &fieldName, const QVariant &value)
Create an expression allowing to evaluate if a field is equal to a value.
QgsAuxiliaryLayer * auxiliaryLayer()
Returns the current auxiliary layer.
static bool deleteTable(const QgsDataSourceUri &uri)
Removes a table from the auxiliary storage.
void setDataType(DataType type)
Sets the data type.
Definition: qgsproperty.h:182
Definition for a property.
Definition: qgsproperty.h:46
QMap< int, QgsPropertyDefinition > QgsPropertiesDefinition
Definition of available properties.
struct sqlite3 sqlite3
QString uri(bool expandAuthConfig=true) const
Returns the complete URI as a string.
static bool exists(const QgsProject &project)
Returns true if the auxiliary database yet exists for a project, false otherwise. ...
Stores the settings for rendering of all diagrams for a layer.
QVector< QgsAttributeTableConfig::ColumnConfig > columns() const
Gets the list with all columns and their configuration.
QgsAttributeTableConfig attributeTableConfig() const
Returns the attribute table configuration object.
QString comment() const
Returns the comment of the property.
Definition: qgsproperty.h:167
void setDataSource(const QString &aSchema, const QString &aTable, const QString &aGeometryColumn, const QString &aSql=QString(), const QString &aKeyColumn=QString())
Sets all data source related members at once.
void setType(QVariant::Type type)
Set variant type.
Definition: qgsfield.cpp:146
void setPrefix(const QString &prefix)
Sets prefix of fields from the joined layer. If nullptr, joined layer&#39;s name will be used...
QgsEditorWidgetSetup editorWidgetSetup(int index) const
The editor widget setup defines which QgsFieldFormatter and editor widget will be used for the field ...
void setColumns(const QVector< QgsAttributeTableConfig::ColumnConfig > &columns)
Set the list of columns visible in the attribute table.
int indexOf(const QString &fieldName) const
Gets the field index from the field name.
Definition: qgsfields.cpp:207
Property requires a string value.
Definition: qgsproperty.h:91
QString source() const
Returns the source for the layer.
QgsAuxiliaryStorage(const QgsProject &project, bool copy=true)
Constructor.
const QgsDiagramLayerSettings * diagramLayerSettings() const
Holder for the widget type and its configuration for a field.
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the diagram property definitions.
void setOrigin(const QString &origin)
Sets the origin of the property.
Definition: qgsproperty.h:157
static QString nameFromProperty(const QgsPropertyDefinition &def, bool joined=false)
Returns the name of the auxiliary field for a property definition.
void setGeometry(const QgsGeometry &geometry)
Set the feature&#39;s geometry.
Definition: qgsfeature.cpp:137
void setComment(const QString &comment)
Sets comment of the property.
Definition: qgsproperty.h:172
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=nullptr) FINAL
Adds a single feature to the sink.
void setCascadedDelete(bool enabled)
Sets whether a feature deleted on the target layer has to impact the joined layer by deleting the cor...
QString errorString() const
Returns the underlying error string describing potential errors happening in saveAs().
A grouped map of multiple QgsProperty objects, each referenced by a integer key value.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
void setJoinFieldNamesBlackList(const QStringList &blackList)
Sets a list of fields to ignore whatever happens.
bool deleteAttribute(int attr) override
Removes attribute from the layer and commits changes.
QgsGeometry geometry
Definition: qgsfeature.h:67
static bool duplicateTable(const QgsDataSourceUri &uri, const QString &newTable)
Duplicates a table and its content.
static QgsVectorLayer * createMemoryLayer(const QString &name, const QgsFields &fields, QgsWkbTypes::Type geometryType=QgsWkbTypes::NoGeometry, const QgsCoordinateReferenceSystem &crs=QgsCoordinateReferenceSystem())
Creates a new memory layer using the specified parameters.
QgsFields auxiliaryFields() const
Returns a list of all auxiliary fields currently managed by the layer.
Y-coordinate data defined label position.
bool nextFeature(QgsFeature &f)
This is a container for configuration of the attribute table.
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the symbol layer property definitions.
Max scale (deprecated, for old project compatibility only)
Class for storing the component parts of a RDBMS data source URI (e.g.
bool addAuxiliaryField(const QgsPropertyDefinition &definition)
Adds an auxiliary field for the given property.
QString absoluteFilePath() const
Returns full absolute path to the project file if the project is stored in a file system - derived fr...
Definition: qgsproject.cpp:630
static QgsPropertyDefinition propertyDefinitionFromField(const QgsField &field)
Returns the property definition from an auxiliary field.
QString name() const
Returns the name of the property.
Definition: qgsproperty.h:138
Represents a vector layer which manages a vector based data sets.
bool addAttribute(const QgsField &field)
Add an attribute field (but does not commit it) returns true if the field was added.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:262
virtual QgsFeatureIds allFeatureIds() const
Returns a list of all feature IDs for features present in the source.
Vertical alignment for data defined label position (Bottom, Base, Half, Cap, Top) ...
Whether all parts of multi-part features should be labeled.
void setAttributeTableConfig(const QgsAttributeTableConfig &attributeTableConfig)
Sets the attribute table configuration object.
QgsField field(int fieldIdx) const
Gets field at particular index (must be in range 0..N-1)
Definition: qgsfields.cpp:168
bool isHiddenProperty(int index) const
Returns true if the underlying field has to be hidden from editing tools like attribute table...
QString database() const
Returns the database name stored in the URI.
QgsAuxiliaryLayer * createAuxiliaryLayer(const QgsField &field, QgsVectorLayer *layer) const
Creates an auxiliary layer for a vector layer.
QVariant::Type type
Definition: qgsfield.h:56
bool saveAs(const QString &filename)
Saves the current database to a new path.
void setDatabase(const QString &database)
Sets the URI database name.
QString origin() const
Returns the origin of the property.
Definition: qgsproperty.h:150
StandardPropertyTemplate standardTemplate() const
Returns the property&#39;s standard template, if applicable.
Definition: qgsproperty.h:193
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:86
QgsVectorLayer * clone() const override
Returns a new instance equivalent to this one.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the label&#39;s property collection, used for data defined overrides.
Color with no alpha channel.
Definition: qgsproperty.h:65