Skip to content
Permalink
Browse files
fix QgsSqlAnywhereProvider::attributeIndexes()
  • Loading branch information
jef-n committed Jan 30, 2013
1 parent 46240bb commit 121ddc79b4b060baab150d28486c5a5ce0357d46
@@ -27,7 +27,7 @@

QgsSqlAnywhereFeatureIterator::QgsSqlAnywhereFeatureIterator( QgsSqlAnywhereProvider* p, const QgsFeatureRequest & request )
: QgsAbstractFeatureIterator( request ), P( p )
, mStmt( NULL ), mStmtRect()
, mStmt( NULL ), mStmtRect()
{

mClosed = false;
@@ -110,35 +110,35 @@ bool QgsSqlAnywhereFeatureIterator::nextFeature( QgsFeature& feature, SqlAnyStat
ok = ( stmt != NULL && stmt->fetchNext() );

// if no more rows...
if( !ok )
if ( !ok )
return false;

if( !fetchGeometry )
if ( !fetchGeometry )
feature.setGeometryAndOwnership( 0, 0 );

int numAttributes = P->fields().count(); // also used later for sanity check

feature.initAttributes( numAttributes );
feature.setFields( &P->mAttributeFields ); // allow name-based attribute lookups

int i = 0;
int numcols = stmt->numCols();
int colidx = 0; // Refers to which column we're on in "feature" (the row)
for( i = 0; i < numcols; i++ )
for ( i = 0; i < numcols; i++ )
{
if( i == 0 )
if ( i == 0 )
{
// first column always contains primary key
ok = stmt->getInt( i, id );
if( !ok ) break;
if ( !ok ) break;
QgsDebugMsgLevel( QString( "pid=%1" ).arg( id ), 3 );
feature.setFeatureId( id );
}
else if( i == 1 && fetchGeometry )
else if ( i == 1 && fetchGeometry )
{
// second column contains QKB geometry value
ok = stmt->getColumn( i, &geom );
if( !ok ) break;
ok = stmt->getColumn( i, &geom );
if ( !ok ) break;
QgsDebugMsgLevel( QString( "retrieved geometry column" ), 3 );
geomBuf = new unsigned char[ *geom.length + 1 ];
memset( geomBuf, '\0', *geom.length );
@@ -147,20 +147,20 @@ bool QgsSqlAnywhereFeatureIterator::nextFeature( QgsFeature& feature, SqlAnyStat
}
else
{
if( i == 1 )
if ( i == 1 )
{
feature.setGeometryAndOwnership( 0, 0 ); // no geometry to fetch
}
int attrIndex = subsetAttributes ? mRequest.subsetOfAttributes()[colidx++] : colidx++;
int attrIndex = subsetAttributes ? mRequest.subsetOfAttributes()[colidx++] : colidx++;
QVariant val;
ok = stmt->getQVariant( i, val ); // ok may be false if value was NULL, but this is a valid return

// Sanity check before setting the attribute value
if( colidx-1 == i // First column is always pk, so colidx should be at least 1 behind
|| ( colidx-1 == i-1 && fetchGeometry ) // if fetchGeometry is true, colidx should be 2 behind
|| attrIndex >= numAttributes ) // index should always be less than the count
if ( colidx - 1 == i // First column is always pk, so colidx should be at least 1 behind
|| ( colidx - 1 == i - 1 && fetchGeometry ) // if fetchGeometry is true, colidx should be 2 behind
|| attrIndex >= numAttributes ) // index should always be less than the count
{
SaDebugMsg( QString("Error retrieving feature column %1 with attribute index %2").arg(i).arg(attrIndex) );
SaDebugMsg( QString( "Error retrieving feature column %1 with attribute index %2" ).arg( i ).arg( attrIndex ) );
return false;
}
// So now this should not crash.
@@ -206,7 +206,7 @@ QgsSqlAnywhereFeatureIterator::prepareStatement( QString whereClause )
if ( !( mRequest.flags() & QgsFeatureRequest::NoGeometry ) && P->mGeometryColumn.isNull() )
return false;

if( !P->ensureConnRO() )
if ( !P->ensureConnRO() )
{
SaDebugMsg( "No read-only database connection." );
return false;
@@ -218,18 +218,19 @@ QgsSqlAnywhereFeatureIterator::prepareStatement( QString whereClause )
if ( !( mRequest.flags() & QgsFeatureRequest::NoGeometry ) )
{
sql += QString( ", %1 .ST_AsBinary('WKB(Version=1.1;endian=%2)') " )
.arg( P->mGeometryColumn )
.arg( QgsApplication::endian() == QgsApplication::XDR ? "xdr" : "ndr" );
.arg( P->mGeometryColumn )
.arg( QgsApplication::endian() == QgsApplication::XDR ? "xdr" : "ndr" );
}

// Add the rest of the columns
if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes )
{
{
const QgsAttributeList& fetchAttributes = mRequest.subsetOfAttributes();
for ( QgsAttributeList::const_iterator it = fetchAttributes.constBegin(); it != fetchAttributes.constEnd(); ++it )
{
QString name = P->field( *it ).name();
if( !name.isEmpty() /*&& name != P->mKeyColumn*/ ) {
if ( !name.isEmpty() /*&& name != P->mKeyColumn*/ )
{
sql += "," + P->quotedIdentifier( name );
}
}
@@ -240,7 +241,8 @@ QgsSqlAnywhereFeatureIterator::prepareStatement( QString whereClause )
for ( int idx = 0; idx < P->mAttributeFields.count(); ++idx )
{
QString name = P->mAttributeFields[idx].name();
if( !name.isEmpty() /*&& name != P->mKeyColumn*/ ) {
if ( !name.isEmpty() /*&& name != P->mKeyColumn*/ )
{
sql += "," + P->quotedIdentifier( name );
}
}
@@ -256,7 +258,7 @@ QgsSqlAnywhereFeatureIterator::prepareStatement( QString whereClause )
delete mStmt;

mStmt = P->mConnRO->prepare( sql );
if( !mStmt->isValid() )
if ( !mStmt->isValid() )
{
// (Error msg will be printed using SaDebugMsg in prepare())
rewind();
@@ -316,7 +318,7 @@ QgsSqlAnywhereFeatureIterator::prepareStatement( QString whereClause )
}

// Execute the statement
if( !mStmt->execute() )
if ( !mStmt->execute() )
{
// (Error msg will be printed using SaDebugMsg in execute())
rewind();
@@ -335,9 +337,9 @@ QgsSqlAnywhereFeatureIterator::whereClauseRect() const
whereClause += QString( "%1 .%2 ( new ST_Polygon( "
"new ST_Point( ?, ?, %3), "
"new ST_Point( ?, ?, %3 ) ) ) = 1 " )
.arg( P->geomColIdent() )
.arg(( exactIntersect ? "ST_Intersects" : "ST_IntersectsFilter" ) )
.arg( P->mSrid );
.arg( P->geomColIdent() )
.arg(( exactIntersect ? "ST_Intersects" : "ST_IntersectsFilter" ) )
.arg( P->mSrid );
// Note: IntersectsFilter is the less expensive estimate

return whereClause;
@@ -39,7 +39,7 @@ class QgsSqlAnywhereFeatureIterator : public QgsAbstractFeatureIterator
* Statement handle for fetching of features by bounding rectangle
*/
SqlAnyStatement *mStmt;

QgsRectangle mStmtRect;

};
@@ -276,10 +276,10 @@ QgsSqlAnywhereProvider::storageType() const
return "SQL Anywhere database";
} // QgsSqlAnywhereProvider::storageType()

QgsFeatureIterator
QgsFeatureIterator
QgsSqlAnywhereProvider::getFeatures( const QgsFeatureRequest& request )
{
if( !mValid )
if ( !mValid )
{
QgsMessageLog::logMessage( tr( "Read attemt on an invalid SqlAnywhere data source" ), tr( "SQLAnywhere" ) );
return QgsFeatureIterator();
@@ -816,7 +816,7 @@ QgsSqlAnywhereProvider::addFeatures( QgsFeatureList & flist )
.arg( mSrid );

// iterate attributes
for( int idx = 0; idx < attrs.count(); ++idx )
for ( int idx = 0; idx < attrs.count(); ++idx )
{
QVariant v = attrs[idx];
QString fieldname = mAttributeFields[idx].name();
@@ -1144,15 +1144,15 @@ QgsSqlAnywhereProvider::changeAttributeValues( const QgsChangedAttributesMap & a
; ait++ )
{
QString attr;
if( ait.key() < mAttributeFields.size() )
if ( ait.key() < mAttributeFields.size() )
{
attr = field( ait.key() ).name();
}
}
sql += ( cnt++ != 0 ? ", " : "" );
sql += QString( "%1=%2" )
.arg( attr )
.arg( quotedValue( ait->toString() ) );

ok = !attr.isEmpty();
}

@@ -1298,7 +1298,10 @@ QgsSqlAnywhereProvider::changeGeometryValues( QgsGeometryMap & gmap )

QgsAttributeList QgsSqlAnywhereProvider::attributeIndexes()
{
return mAttributeFields.keys();
QgsAttributeList lst;
for ( int i = 0; i < mAttributeFields.count(); ++i )
lst.append( i );
return lst;
}

bool
@@ -119,15 +119,15 @@ class QgsSqlAnywhereProvider: public QgsVectorDataProvider
* @param limit maximum number of values (added in 1.4) */
virtual void uniqueValues( int index, QList < QVariant > &uniqueValues, int limit = -1 );

/** Returns the possible enum values of an attribute.
* Returns an empty stringlist if a provider does not support enum types
* or if the given attribute is not an enum type.
* @param index the index of the attribute
* @param enumList reference to the list to fill
* @note: added in version 1.2
* SQLAnywhere does not currently support enumerated types.
*/
//virtual void enumValues( int index, QStringList& enumList );
/** Returns the possible enum values of an attribute.
* Returns an empty stringlist if a provider does not support enum types
* or if the given attribute is not an enum type.
* @param index the index of the attribute
* @param enumList reference to the list to fill
* @note: added in version 1.2
* SQLAnywhere does not currently support enumerated types.
*/
//virtual void enumValues( int index, QStringList& enumList );

/**Returns true if layer is valid
*/

0 comments on commit 121ddc7

Please sign in to comment.