QGIS API Documentation  3.4.3-Madeira (2f64a3c)
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 : paul.blottiere@oslandia.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 #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 {
57 };
58 
59 //
60 // QgsAuxiliaryLayer
61 //
62 
63 QgsAuxiliaryLayer::QgsAuxiliaryLayer( const QString &pkField, const QString &filename, const QString &table, QgsVectorLayer *vlayer )
64  : QgsVectorLayer( QString( "%1|layername=%2" ).arg( filename, table ), QString( "%1_auxiliarystorage" ).arg( table ), "ogr" )
65  , mFileName( filename )
66  , mTable( table )
67  , mLayer( vlayer )
68 {
69  // init join info
70  mJoinInfo.setPrefix( AS_JOINPREFIX );
71  mJoinInfo.setJoinLayer( this );
72  mJoinInfo.setJoinFieldName( AS_JOINFIELD );
73  mJoinInfo.setTargetFieldName( pkField );
74  mJoinInfo.setEditable( true );
75  mJoinInfo.setUpsertOnEdit( true );
76  mJoinInfo.setCascadedDelete( true );
77  mJoinInfo.setJoinFieldNamesBlackList( QStringList() << QStringLiteral( "rowid" ) ); // introduced by ogr provider
78 }
79 
81 {
83  return new QgsAuxiliaryLayer( mJoinInfo.targetFieldName(), mFileName, target->id(), target );
84 }
85 
87 {
88  bool rc = deleteFeatures( allFeatureIds() );
89  commitChanges();
90  startEditing();
91  return rc;
92 }
93 
95 {
96  QgsVectorLayer *layer = QgsMemoryProviderUtils::createMemoryLayer( QStringLiteral( "auxiliary_layer" ), fields(), mLayer->wkbType(), mLayer->crs() );
97 
98  QString pkField = mJoinInfo.targetFieldName();
99  QgsFeature joinFeature;
100  QgsFeature targetFeature;
102 
103  layer->startEditing();
104  while ( it.nextFeature( joinFeature ) )
105  {
106  QString filter = QgsExpression::createFieldEqualityExpression( pkField, joinFeature.attribute( AS_JOINFIELD ) );
107 
108  QgsFeatureRequest request;
109  request.setFilterExpression( filter );
110 
111  mLayer->getFeatures( request ).nextFeature( targetFeature );
112 
113  if ( targetFeature.isValid() )
114  {
115  QgsFeature newFeature( joinFeature );
116  newFeature.setGeometry( targetFeature.geometry() );
117  layer->addFeature( newFeature );
118  }
119  }
120  layer->commitChanges();
121 
122  return layer;
123 }
124 
126 {
127  return mJoinInfo;
128 }
129 
130 bool QgsAuxiliaryLayer::exists( const QgsPropertyDefinition &definition ) const
131 {
132  return ( indexOfPropertyDefinition( definition ) >= 0 );
133 }
134 
136 {
137  if ( ( definition.name().isEmpty() && definition.comment().isEmpty() ) || exists( definition ) )
138  return false;
139 
140  const QgsField af = createAuxiliaryField( definition );
141  const bool rc = addAttribute( af );
142  updateFields();
143  mLayer->updateFields();
144 
145  if ( rc )
146  {
147  int auxIndex = indexOfPropertyDefinition( definition );
148  int index = mLayer->fields().indexOf( nameFromProperty( definition, true ) );
149 
150  if ( index >= 0 && auxIndex >= 0 )
151  {
152  if ( isHiddenProperty( auxIndex ) )
153  {
154  // update editor widget
155  QgsEditorWidgetSetup setup = QgsEditorWidgetSetup( QStringLiteral( "Hidden" ), QVariantMap() );
156  setEditorWidgetSetup( auxIndex, setup );
157 
158  // column is hidden
159  QgsAttributeTableConfig attrCfg = mLayer->attributeTableConfig();
160  attrCfg.update( mLayer->fields() );
161  QVector<QgsAttributeTableConfig::ColumnConfig> columns = attrCfg.columns();
162  QVector<QgsAttributeTableConfig::ColumnConfig>::iterator it;
163 
164  for ( it = columns.begin(); it != columns.end(); ++it )
165  {
166  if ( it->name.compare( mLayer->fields().field( index ).name() ) == 0 )
167  it->hidden = true;
168  }
169 
170  attrCfg.setColumns( columns );
171  mLayer->setAttributeTableConfig( attrCfg );
172  }
173  else if ( definition.standardTemplate() == QgsPropertyDefinition::ColorNoAlpha
175  {
176  QgsEditorWidgetSetup setup = QgsEditorWidgetSetup( QStringLiteral( "Color" ), QVariantMap() );
177  setEditorWidgetSetup( auxIndex, setup );
178  }
179 
180  mLayer->setEditorWidgetSetup( index, editorWidgetSetup( auxIndex ) );
181  }
182  }
183 
184  return rc;
185 }
186 
188 {
189  QgsFields afields;
190 
191  for ( int i = 2; i < fields().count(); i++ ) // ignore rowid and PK field
192  afields.append( createAuxiliaryField( fields().field( i ) ) );
193 
194  return afields;
195 }
196 
198 {
200  bool rc = commitChanges();
201  startEditing();
202  return rc;
203 }
204 
206 {
207  bool rc = false;
208 
209  if ( isEditable() )
210  {
211  rc = commitChanges();
212  }
213 
214  startEditing();
215 
216  return rc;
217 }
218 
220 {
221  int index = -1;
222 
223  if ( layer && layer->labeling() && layer->auxiliaryLayer() )
224  {
225  // property definition are identical whatever the provider id
226  const QgsPropertyDefinition def = layer->labeling()->settings().propertyDefinitions()[property];
227  const QString fieldName = nameFromProperty( def, true );
228 
229  layer->auxiliaryLayer()->addAuxiliaryField( def );
230 
231  if ( layer->auxiliaryLayer()->indexOfPropertyDefinition( def ) >= 0 )
232  {
233  const QgsProperty prop = QgsProperty::fromField( fieldName );
234 
235  const QStringList subProviderIds = layer->labeling()->subProviders();
236  for ( const QString &providerId : subProviderIds )
237  {
238  QgsPalLayerSettings *settings = new QgsPalLayerSettings( layer->labeling()->settings( providerId ) );
239 
241  c.setProperty( property, prop );
242  settings->setDataDefinedProperties( c );
243 
244  layer->labeling()->setSettings( settings, providerId );
245  }
246 
247  emit layer->styleChanged();
248  }
249 
250  index = layer->fields().lookupField( fieldName );
251  }
252 
253  return index;
254 }
255 
257 {
258  int index = -1;
259 
260  if ( layer && layer->diagramLayerSettings() && layer->auxiliaryLayer() )
261  {
262  const QgsPropertyDefinition def = layer->diagramLayerSettings()->propertyDefinitions()[property];
263 
264  if ( layer->auxiliaryLayer()->addAuxiliaryField( def ) )
265  {
266  const QString fieldName = nameFromProperty( def, true );
267  const QgsProperty prop = QgsProperty::fromField( fieldName );
268 
269  QgsDiagramLayerSettings settings( *layer->diagramLayerSettings() );
270 
271  QgsPropertyCollection c = settings.dataDefinedProperties();
272  c.setProperty( property, prop );
273  settings.setDataDefinedProperties( c );
274 
275  layer->setDiagramLayerSettings( settings );
276  emit layer->styleChanged();
277 
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( "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 = QString( "%1_%2" ).arg( fieldName, def.name().toLower() );
370 
371  if ( !def.comment().isEmpty() )
372  fieldName = QString( "%1_%2" ).arg( fieldName, def.comment() );
373 
374  if ( joined )
375  fieldName = QString( "%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 = "String";
395  break;
397  type = QVariant::Double;
398  len = 0;
399  precision = 0;
400  typeName = "Real";
401  break;
403  type = QVariant::Int; // sqlite does not have a bool type
404  typeName = "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( "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[2] );
439  break;
440  }
441  }
442  }
443  else if ( origin.compare( "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[2] );
453  break;
454  }
455  }
456  }
457  else if ( origin.compare( "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[2] );
467  break;
468  }
469  }
470  }
471  else
472  {
473  def.setOrigin( origin );
474  def.setName( propertyName );
475 
476  if ( parts.size() == 3 )
477  def.setComment( parts[2] );
478  }
479 
480  return def;
481 }
482 
484 {
486  QgsField afield;
487 
488  if ( !def.name().isEmpty() || !def.comment().isEmpty() )
489  {
490  afield = createAuxiliaryField( def );
491  afield.setTypeName( field.typeName() );
492  }
493 
494  return afield;
495 }
496 
497 //
498 // QgsAuxiliaryStorage
499 //
500 
502  : mCopy( copy )
503 {
504  initTmpFileName();
505 
506  if ( !project.absoluteFilePath().isEmpty() )
507  {
508  mFileName = filenameForProject( project );
509  }
510 
511  open( mFileName );
512 }
513 
514 QgsAuxiliaryStorage::QgsAuxiliaryStorage( const QString &filename, bool copy )
515  : mFileName( filename )
516  , mCopy( copy )
517 {
518  initTmpFileName();
519 
520  open( filename );
521 }
522 
524 {
525  QFile::remove( mTmpFileName );
526 }
527 
529 {
530  return mValid;
531 }
532 
534 {
535  return mFileName;
536 }
537 
539 {
540  if ( mFileName.isEmpty() )
541  {
542  // only a saveAs is available on a new database
543  return false;
544  }
545  else if ( mCopy )
546  {
547  if ( QFile::exists( mFileName ) )
548  QFile::remove( mFileName );
549 
550  return QFile::copy( mTmpFileName, mFileName );
551  }
552  else
553  {
554  // if the file is not empty the copy mode is not activated, then we're
555  // directly working on the database since the beginning (no savepoints
556  // /rollback for now)
557  return true;
558  }
559 }
560 
562 {
563  QgsAuxiliaryLayer *alayer = nullptr;
564 
565  if ( mValid && layer )
566  {
567  const QString table( layer->id() );
569  database = openDB( currentFileName() );
570 
571  if ( !tableExists( table, database.get() ) )
572  {
573  if ( !createTable( field.typeName(), table, database.get() ) )
574  {
575  return alayer;
576  }
577  }
578 
579  alayer = new QgsAuxiliaryLayer( field.name(), currentFileName(), table, layer );
580  alayer->startEditing();
581  }
582 
583  return alayer;
584 }
585 
587 {
588  bool rc = false;
589  QgsDataSourceUri uri = parseOgrUri( ogrUri );
590 
591  if ( !uri.database().isEmpty() && !uri.table().isEmpty() )
592  {
594  database = openDB( uri.database() );
595 
596  if ( database )
597  {
598  QString sql = QString( "DROP TABLE %1" ).arg( uri.table() );
599  rc = exec( sql, database.get() );
600 
601  sql = QStringLiteral( "VACUUM" );
602  rc = exec( sql, database.get() );
603  }
604  }
605 
606  return rc;
607 }
608 
609 bool QgsAuxiliaryStorage::duplicateTable( const QgsDataSourceUri &ogrUri, const QString &newTable )
610 {
611  QgsDataSourceUri uri = parseOgrUri( ogrUri );
612  bool rc = false;
613 
614  if ( !uri.table().isEmpty() && !uri.database().isEmpty() )
615  {
617  database = openDB( uri.database() );
618 
619  if ( database )
620  {
621  QString sql = QStringLiteral( "CREATE TABLE %1 AS SELECT * FROM %2" ).arg( newTable, uri.table() );
622  rc = exec( sql, database.get() );
623  }
624  }
625 
626  return rc;
627 }
628 
630 {
631  return mErrorString;
632 }
633 
634 bool QgsAuxiliaryStorage::saveAs( const QString &filename )
635 {
636  mErrorString.clear();
637 
638  QFile dest( filename );
639  if ( dest.exists() && !dest.remove() )
640  {
641  mErrorString = dest.errorString();
642  return false;
643  }
644 
645  QFile origin( currentFileName() );
646  if ( !origin.copy( filename ) )
647  {
648  mErrorString = origin.errorString();
649  return false;
650  }
651 
652  return true;
653 }
654 
656 {
657  return saveAs( filenameForProject( project ) );
658 }
659 
661 {
662  return AS_EXTENSION;
663 }
664 
666 {
667  const QFileInfo fileinfo( filenameForProject( project ) );
668  return fileinfo.exists() && fileinfo.isFile();
669 }
670 
671 bool QgsAuxiliaryStorage::exec( const QString &sql, sqlite3 *handler )
672 {
673  bool rc = false;
674 
675  if ( handler )
676  {
677  const int err = sqlite3_exec( handler, sql.toStdString().c_str(), nullptr, nullptr, nullptr );
678 
679  if ( err == SQLITE_OK )
680  rc = true;
681  else
682  debugMsg( sql, handler );
683  }
684 
685  return rc;
686 }
687 
688 void QgsAuxiliaryStorage::debugMsg( const QString &sql, sqlite3 *handler )
689 {
690 #ifdef QGISDEBUG
691  const QString err = QString::fromUtf8( sqlite3_errmsg( handler ) );
692  const QString msg = QObject::tr( "Unable to execute" );
693  const QString errMsg = QObject::tr( "%1 '%2': %3" ).arg( msg, sql, err );
694  QgsDebugMsg( errMsg );
695 #else
696  Q_UNUSED( sql );
697  Q_UNUSED( handler );
698 #endif
699 }
700 
701 bool QgsAuxiliaryStorage::createTable( const QString &type, const QString &table, sqlite3 *handler )
702 {
703  const QString sql = QStringLiteral( "CREATE TABLE IF NOT EXISTS '%1' ( '%2' %3 )" ).arg( table, AS_JOINFIELD, type );
704 
705  if ( !exec( sql, handler ) )
706  return false;
707 
708  return true;
709 }
710 
711 spatialite_database_unique_ptr QgsAuxiliaryStorage::createDB( const QString &filename )
712 {
714 
715  int rc;
716  rc = database.open_v2( filename, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr );
717  if ( rc )
718  {
719  debugMsg( QStringLiteral( "sqlite3_open_v2" ), database.get() );
720  }
721  else
722  // activating Foreign Key constraints
723  exec( QStringLiteral( "PRAGMA foreign_keys = 1" ), database.get() );
724 
725  return database;
726 }
727 
728 spatialite_database_unique_ptr QgsAuxiliaryStorage::openDB( const QString &filename )
729 {
731  int rc = database.open_v2( filename, SQLITE_OPEN_READWRITE, nullptr );
732 
733  if ( rc )
734  {
735  debugMsg( "sqlite3_open_v2", database.get() );
736  }
737 
738  return database;
739 }
740 
741 bool QgsAuxiliaryStorage::tableExists( const QString &table, sqlite3 *handler )
742 {
743  const QString sql = QStringLiteral( "SELECT 1 FROM sqlite_master WHERE type='table' AND name='%1'" ).arg( table );
744  int rows = 0;
745  int columns = 0;
746  char **results = nullptr;
747  const int rc = sqlite3_get_table( handler, sql.toStdString().c_str(), &results, &rows, &columns, nullptr );
748  if ( rc != SQLITE_OK )
749  {
750  debugMsg( sql, handler );
751  return false;
752  }
753 
754  sqlite3_free_table( results );
755  if ( rows >= 1 )
756  return true;
757 
758  return false;
759 }
760 
761 spatialite_database_unique_ptr QgsAuxiliaryStorage::open( const QString &filename )
762 {
764 
765  if ( filename.isEmpty() )
766  {
767  if ( ( database = createDB( currentFileName() ) ) )
768  mValid = true;
769  }
770  else if ( QFile::exists( filename ) )
771  {
772  if ( mCopy )
773  QFile::copy( filename, mTmpFileName );
774 
775  if ( ( database = openDB( currentFileName() ) ) )
776  mValid = true;
777  }
778  else
779  {
780  if ( ( database = createDB( currentFileName() ) ) )
781  mValid = true;
782  }
783 
784  return database;
785 }
786 
787 spatialite_database_unique_ptr QgsAuxiliaryStorage::open( const QgsProject &project )
788 {
789  return open( filenameForProject( project ) );
790 }
791 
792 QString QgsAuxiliaryStorage::filenameForProject( const QgsProject &project )
793 {
794  const QFileInfo info( project.absoluteFilePath() );
795  const QString path = info.path() + QDir::separator() + info.baseName();
796  return path + '.' + QgsAuxiliaryStorage::extension();
797 }
798 
799 void QgsAuxiliaryStorage::initTmpFileName()
800 {
801  QTemporaryFile tmpFile;
802  tmpFile.open();
803  tmpFile.close();
804  mTmpFileName = tmpFile.fileName();
805 }
806 
808 {
809  if ( mCopy || mFileName.isEmpty() )
810  return mTmpFileName;
811  else
812  return mFileName;
813 }
814 
815 QgsDataSourceUri QgsAuxiliaryStorage::parseOgrUri( const QgsDataSourceUri &uri )
816 {
817  QgsDataSourceUri newUri;
818 
819  // parsing for ogr style uri :
820  // " filePath|layername='tableName' table="" sql="
821  QStringList uriParts = uri.uri().split( '|' );
822  if ( uriParts.count() < 2 )
823  return newUri;
824 
825  const QString databasePath = uriParts[0].replace( ' ', "" );
826 
827  const QString table = uriParts[1];
828  QStringList tableParts = table.split( ' ' );
829 
830  if ( tableParts.count() < 1 )
831  return newUri;
832 
833  const QString tableName = tableParts[0].replace( QStringLiteral( "layername=" ), QString() );
834 
835  newUri.setDataSource( QString(), tableName, QString() );
836  newUri.setDatabase( databasePath );
837 
838  return newUri;
839 }
void setProperty(int key, const QgsProperty &property)
Adds a property to the collection and takes ownership of it.
int lookupField(const QString &fieldName) const
Look up field&#39;s index from the field name.
Definition: qgsfields.cpp:302
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.
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.
QString name
Definition: qgsfield.h:57
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:160
#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:136
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
QgsMapLayer::LayerType type() const
Returns the type of the layer.
int count() const
Returns number of items.
Definition: qgsfields.cpp:115
static QString extension()
Returns the extension used for auxiliary databases.
void styleChanged()
Signal emitted whenever a change affects the layer&#39;s style.
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:156
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:151
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)
Append a field. The field must have unique name, otherwise it is rejected (returns false) ...
Definition: qgsfields.cpp:59
Reads and writes project states.
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.
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 complete uri.
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:141
void setPrefix(const QString &prefix)
Sets prefix of fields from the joined layer. If null, 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:189
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 hapenning in saveAs().
A grouped map of multiple QgsProperty objects, each referenced by a integer key value.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Query 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 PostgreSQL/RDBMS datasource URI.
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:592
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) ...
void setAttributeTableConfig(const QgsAttributeTableConfig &attributeTableConfig)
Set 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:150
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.
QgsAuxiliaryLayer * createAuxiliaryLayer(const QgsField &field, QgsVectorLayer *layer) const
Creates an auxiliary layer for a vector layer.
bool saveAs(const QString &filename)
Saves the current database to a new path.
void setDatabase(const QString &database)
Sets database.
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:70
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