QgsPostgresFeatureIterator::QgsPostgresFeatureIterator( QgsPostgresFeatureSource* source, bool ownSource, const QgsFeatureRequest& request ) : QgsAbstractFeatureIteratorFromSource<QgsPostgresFeatureSource>( source, ownSource, request ) , mFeatureQueueSize( sFeatureQueueSize ) , mFetched( 0 ) , mFetchGeometry( false ) , mExpressionCompiled( false ) , mLastFetch( false ) { if ( !source->mTransactionConnection ) { mConn = QgsPostgresConnPool::instance()->acquireConnection( mSource->mConnInfo ); mIsTransactionConnection = false; } else { mConn = source->mTransactionConnection; mConn->lock(); mIsTransactionConnection = true; } if ( !mConn ) { mClosed = true; iteratorClosed(); return; } mCursorName = mConn->uniqueCursorName(); QString whereClause; if ( !request.filterRect().isNull() && !mSource->mGeometryColumn.isNull() ) { whereClause = whereClauseRect(); } if ( request.filterType() == QgsFeatureRequest::FilterFid ) { QString fidWhereClause = QgsPostgresUtils::whereClause( mRequest.filterFid(), mSource->mFields, mConn, mSource->mPrimaryKeyType, mSource->mPrimaryKeyAttrs, mSource->mShared ); whereClause = QgsPostgresUtils::andWhereClauses( whereClause, fidWhereClause ); } else if ( request.filterType() == QgsFeatureRequest::FilterFids ) { QString fidsWhereClause = QgsPostgresUtils::whereClause( mRequest.filterFids(), mSource->mFields, mConn, mSource->mPrimaryKeyType, mSource->mPrimaryKeyAttrs, mSource->mShared ); whereClause = QgsPostgresUtils::andWhereClauses( whereClause, fidsWhereClause ); } else if ( request.filterType() == QgsFeatureRequest::FilterExpression && QSettings().value( "/qgis/compileExpressions", true ).toBool() ) { QgsPostgresExpressionCompiler compiler = QgsPostgresExpressionCompiler( source ); if ( compiler.compile( request.filterExpression() ) == QgsSqlExpressionCompiler::Complete ) { whereClause = QgsPostgresUtils::andWhereClauses( whereClause, compiler.result() ); mExpressionCompiled = true; } } if ( !mSource->mSqlWhereClause.isEmpty() ) { if ( !whereClause.isEmpty() ) whereClause += " AND "; whereClause += '(' + mSource->mSqlWhereClause + ')'; } if ( !declareCursor( whereClause ) ) { mClosed = true; iteratorClosed(); return; } mFetched = 0; }
QgsPostgresFeatureIterator::QgsPostgresFeatureIterator( QgsPostgresFeatureSource* source, bool ownSource, const QgsFeatureRequest& request ) : QgsAbstractFeatureIteratorFromSource<QgsPostgresFeatureSource>( source, ownSource, request ) , mFeatureQueueSize( sFeatureQueueSize ) , mFetched( 0 ) , mFetchGeometry( false ) , mExpressionCompiled( false ) , mOrderByCompiled( false ) , mLastFetch( false ) , mFilterRequiresGeometry( false ) { if ( !source->mTransactionConnection ) { mConn = QgsPostgresConnPool::instance()->acquireConnection( mSource->mConnInfo ); mIsTransactionConnection = false; } else { mConn = source->mTransactionConnection; mIsTransactionConnection = true; } if ( !mConn ) { mClosed = true; iteratorClosed(); return; } mCursorName = mConn->uniqueCursorName(); QString whereClause; bool limitAtProvider = ( mRequest.limit() >= 0 ); bool useFallbackWhereClause = false; QString fallbackWhereClause; if ( !request.filterRect().isNull() && !mSource->mGeometryColumn.isNull() ) { whereClause = whereClauseRect(); } if ( !mSource->mSqlWhereClause.isEmpty() ) { whereClause = QgsPostgresUtils::andWhereClauses( whereClause, '(' + mSource->mSqlWhereClause + ')' ); } if ( request.filterType() == QgsFeatureRequest::FilterFid ) { QString fidWhereClause = QgsPostgresUtils::whereClause( mRequest.filterFid(), mSource->mFields, mConn, mSource->mPrimaryKeyType, mSource->mPrimaryKeyAttrs, mSource->mShared ); whereClause = QgsPostgresUtils::andWhereClauses( whereClause, fidWhereClause ); } else if ( request.filterType() == QgsFeatureRequest::FilterFids ) { QString fidsWhereClause = QgsPostgresUtils::whereClause( mRequest.filterFids(), mSource->mFields, mConn, mSource->mPrimaryKeyType, mSource->mPrimaryKeyAttrs, mSource->mShared ); whereClause = QgsPostgresUtils::andWhereClauses( whereClause, fidsWhereClause ); } else if ( request.filterType() == QgsFeatureRequest::FilterExpression ) { // ensure that all attributes required for expression filter are being fetched if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ) { QgsAttributeList attrs = mRequest.subsetOfAttributes(); Q_FOREACH ( const QString& field, request.filterExpression()->referencedColumns() ) { int attrIdx = mSource->mFields.fieldNameIndex( field ); if ( !attrs.contains( attrIdx ) ) attrs << attrIdx; } mRequest.setSubsetOfAttributes( attrs ); } mFilterRequiresGeometry = request.filterExpression()->needsGeometry(); if ( QSettings().value( "/qgis/compileExpressions", true ).toBool() ) { //IMPORTANT - this MUST be the last clause added! QgsPostgresExpressionCompiler compiler = QgsPostgresExpressionCompiler( source ); if ( compiler.compile( request.filterExpression() ) == QgsSqlExpressionCompiler::Complete ) { useFallbackWhereClause = true; fallbackWhereClause = whereClause; whereClause = QgsPostgresUtils::andWhereClauses( whereClause, compiler.result() ); mExpressionCompiled = true; mCompileStatus = Compiled; } else { limitAtProvider = false; } } else { limitAtProvider = false; } }