Skip to content

Commit

Permalink
Fetch features asynchronously from the database server. This improves…
Browse files Browse the repository at this point in the history
… performance, especially if the db is located on a remote computer. Plus fixed a memory leak in qgsfeature that is important for postgres provider

git-svn-id: http://svn.osgeo.org/qgis/trunk@7269 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
mhugent committed Oct 13, 2007
1 parent 721c2a7 commit e47e592
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 14 deletions.
1 change: 1 addition & 0 deletions src/core/qgsfeature.cpp
Expand Up @@ -124,6 +124,7 @@ QgsFeature & QgsFeature::operator=( QgsFeature const & rhs )
mTypeName = rhs.mTypeName;

// copy embedded geometry
delete mGeometry;
if ( rhs.mGeometry )
{
mGeometry = new QgsGeometry( *(rhs.mGeometry) );
Expand Down
37 changes: 23 additions & 14 deletions src/providers/postgres/qgspostgresprovider.cpp
Expand Up @@ -68,7 +68,7 @@ const QString POSTGRES_DESCRIPTION = "PostgreSQL/PostGIS data provider";
QgsPostgresProvider::QgsPostgresProvider(QString const & uri)
: QgsVectorDataProvider(uri),
geomType(QGis::WKBUnknown),
mFeatureQueueSize(200),
mFeatureQueueSize(200),
gotPostgisVersion(FALSE)
{
// assume this is a valid layer until we determine otherwise
Expand Down Expand Up @@ -397,9 +397,18 @@ bool QgsPostgresProvider::getNextFeature(QgsFeature& feature)
{
QString fetch = QString("fetch forward %1 from qgisf")
.arg(mFeatureQueueSize);

queryResult = PQexec(connection, (const char *)fetch);


if(mFirstFetch)
{
if(PQsendQuery(connection, (const char *)fetch) == 0) //fetch features in asynchronously
{
qWarning("PQsendQuery failed (1)");
}
}
mFirstFetch = false;
queryResult = PQgetResult(connection);
PGresult* bla = PQgetResult(connection); //just to get the 0 pointer...

int rows = PQntuples(queryResult);

if (rows == 0)
Expand Down Expand Up @@ -434,7 +443,7 @@ bool QgsPostgresProvider::getNextFeature(QgsFeature& feature)
char* attribute = PQgetvalue(queryResult, row, PQfnumber(queryResult,*name_it));

QString val = QString::fromUtf8(attribute);
switch (attributeFields[*index_it].type())
switch (attributeFields[*index_it].type())
{
case QVariant::Int:
feature.addAttribute(*index_it, val.toInt());
Expand Down Expand Up @@ -463,19 +472,20 @@ bool QgsPostgresProvider::getNextFeature(QgsFeature& feature)
}
else
{
//QgsDebugMsg("Couldn't get the feature geometry in binary form");
QgsDebugMsg("Couldn't get the feature geometry in binary form");
}
}

//QgsDebugMsg(" pushing " + QString::number(f->featureId());
}

mFeatureQueue.push(feature);

} // for each row in queue

//QgsDebugMsg("retrieved batch of features.");

PQclear(queryResult);

if(PQsendQuery(connection, (const char *)fetch) == 0) //already fetch the next couple of features asynchronously
{
qWarning("PQsendQuery failed (2)");
}

} // if new queue is required

Expand All @@ -486,11 +496,9 @@ bool QgsPostgresProvider::getNextFeature(QgsFeature& feature)
}
else
{
//QgsDebugMsg("Read attempt on an invalid postgresql data source");
QgsDebugMsg("Read attempt on an invalid postgresql data source");
return false;
}

//QgsDebugMsg("returning feature " + QString::number(feat.featureId()));

return true;
}
Expand Down Expand Up @@ -583,6 +591,7 @@ void QgsPostgresProvider::select(QgsAttributeList fetchAttributes,
PQexec(connection, (const char *)(declare.utf8()));

mFeatureQueue.empty();
mFirstFetch = true;
}

bool QgsPostgresProvider::getFeatureAtId(int featureId,
Expand Down
1 change: 1 addition & 0 deletions src/providers/postgres/qgspostgresprovider.h
Expand Up @@ -328,6 +328,7 @@ class QgsPostgresProvider:public QgsVectorDataProvider

private:

bool mFirstFetch; //true if fetch forward is called the first time after select
std::vector < QgsFeature > features;
QgsFieldMap attributeFields;
QString mDataComment;
Expand Down

0 comments on commit e47e592

Please sign in to comment.