Skip to content

Commit

Permalink
Improved fix for spatialite views (fixes #14232)
Browse files Browse the repository at this point in the history
  • Loading branch information
wonder-sk committed Mar 6, 2016
1 parent 5bb25d8 commit 42d8884
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 19 deletions.
2 changes: 1 addition & 1 deletion src/providers/spatialite/qgsspatialitefeatureiterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ bool QgsSpatiaLiteFeatureIterator::prepareStatement( const QString& whereClause,

QString QgsSpatiaLiteFeatureIterator::quotedPrimaryKey()
{
return !( mSource->isQuery || mSource->mViewBased ) ? "ROWID" : QgsSpatiaLiteProvider::quotedIdentifier( mSource->mPrimaryKey );
return mSource->mPrimaryKey.isEmpty() ? "ROWID" : QgsSpatiaLiteProvider::quotedIdentifier( mSource->mPrimaryKey );
}

QString QgsSpatiaLiteFeatureIterator::whereClauseFid()
Expand Down
52 changes: 34 additions & 18 deletions src/providers/spatialite/qgsspatialiteprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,12 @@ void QgsSpatiaLiteProvider::loadFieldsAbstractInterface( gaiaVectorLayerPtr lyr
}
}

// for views try to get the primary key from the meta table
if ( mViewBased && mPrimaryKey.isEmpty() )
{
determineViewPrimaryKey();
}

updatePrimaryKeyCapabilities();

sqlite3_free_table( results );
Expand Down Expand Up @@ -798,26 +804,9 @@ void QgsSpatiaLiteProvider::loadFields()
// for views try to get the primary key from the meta table
if ( mViewBased && mPrimaryKey.isEmpty() )
{
QString sql = QString( "SELECT view_rowid"
" FROM views_geometry_columns"
" WHERE upper(view_name) = upper(%1) and upper(view_geometry) = upper(%2)" ).arg( quotedValue( mTableName ),
quotedValue( mGeometryColumn ) );

ret = sqlite3_get_table( sqliteHandle, sql.toUtf8().constData(), &results, &rows, &columns, &errMsg );
if ( ret == SQLITE_OK )
{
if ( rows > 0 )
{
mPrimaryKey = results[1 * columns];
int idx = attributeFields.fieldNameIndex( mPrimaryKey );
if ( idx != -1 )
mPrimaryKeyAttrs << idx;
}
sqlite3_free_table( results );
}
determineViewPrimaryKey();
}


}
else
{
Expand Down Expand Up @@ -906,6 +895,33 @@ void QgsSpatiaLiteProvider::loadFields()
}
}


void QgsSpatiaLiteProvider::determineViewPrimaryKey()
{
QString sql = QString( "SELECT view_rowid"
" FROM views_geometry_columns"
" WHERE upper(view_name) = upper(%1) and upper(view_geometry) = upper(%2)" ).arg( quotedValue( mTableName ),
quotedValue( mGeometryColumn ) );

char **results;
int rows;
int columns;
char *errMsg = nullptr;
int ret = sqlite3_get_table( sqliteHandle, sql.toUtf8().constData(), &results, &rows, &columns, &errMsg );
if ( ret == SQLITE_OK )
{
if ( rows > 0 )
{
mPrimaryKey = results[1 * columns];
int idx = attributeFields.fieldNameIndex( mPrimaryKey );
if ( idx != -1 )
mPrimaryKeyAttrs << idx;
}
sqlite3_free_table( results );
}
}


bool QgsSpatiaLiteProvider::hasTriggers()
{
int ret;
Expand Down
3 changes: 3 additions & 0 deletions src/providers/spatialite/qgsspatialiteprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,9 @@ class QgsSpatiaLiteProvider: public QgsVectorDataProvider
/** Loads fields from input file to member attributeFields */
void loadFields();

/** For views, try to get primary key from a dedicated meta table */
void determineViewPrimaryKey();

/** Check if a table/view has any triggers. Triggers can be used on views to make them editable.*/
bool hasTriggers();

Expand Down

5 comments on commit 42d8884

@nyalldawson
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wonder-sk is it safe for me to backport this to 2.14?

@wonder-sk
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I'm just waiting for the original reporter to confirm that the problems are gone before backporting it to 2.14

@Roel
Copy link
Contributor

@Roel Roel commented on 42d8884 Mar 9, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to add support for backporting. I have Spatialite views that show correctly on the map in QGis 2.12 but fail to be rendered in 2.14 (the attribute table loads correctly but the layer is not drawn on the map). I traced it back to commit f028c0b where the problem first occurred. It is fixed in master since this commit, so I'm in favor of backporting to 2.14 to fix rendering of Spatialite views. Thanks!

@wonder-sk
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backported to 2.14 in 780c587

@brusspi
Copy link

@brusspi brusspi commented on 42d8884 Oct 2, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that the problem still exists in version 2.16.2. I updated to 2.16.3 and even there it occured.

When selecting a feature it shows the correct values. But when you open the feature form, it always gives the values of the feature with the first ID.
spatialite_view

Please sign in to comment.