[QGIS Commit] r8285 - trunk/qgis/src/providers/postgres
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Wed Mar 26 20:44:22 EDT 2008
Author: jef
Date: 2008-03-26 20:44:22 -0400 (Wed, 26 Mar 2008)
New Revision: 8285
Modified:
trunk/qgis/src/providers/postgres/qgspostgresprovider.cpp
trunk/qgis/src/providers/postgres/qgspostgresprovider.h
Log:
More work on the postgres provider:
- put common code from select/getNextFeature and getFeatureById methods
to new declareCursor and getFeature methods
- unify type handling and support bool, arrays and time types
(fixes #1009)
- ignore columns not explicitly supported (might apply to columns
previously supported implicitly; please file a bug if you run into
one)
- fixes a unreported problem with getFeatureById returning only NULL
attributes.
Please test!
Modified: trunk/qgis/src/providers/postgres/qgspostgresprovider.cpp
===================================================================
--- trunk/qgis/src/providers/postgres/qgspostgresprovider.cpp 2008-03-26 21:07:02 UTC (rev 8284)
+++ trunk/qgis/src/providers/postgres/qgspostgresprovider.cpp 2008-03-27 00:44:22 UTC (rev 8285)
@@ -65,7 +65,8 @@
: QgsVectorDataProvider(uri),
geomType(QGis::WKBUnknown),
mFeatureQueueSize(200),
- gotPostgisVersion(FALSE)
+ gotPostgisVersion(false),
+ mFetching(false)
{
// assume this is a valid layer until we determine otherwise
valid = true;
@@ -366,388 +367,294 @@
return "PostgreSQL database with PostGIS extension";
}
-bool QgsPostgresProvider::getNextFeature(QgsFeature& feature)
+void QgsPostgresProvider::declareCursor(const QString &cursorName,
+ const QgsAttributeList &fetchAttributes,
+ bool fetchGeometry,
+ QString whereClause,
+ QStringList &attributeNames)
{
- assert(mFetching);
+ QString declare = QString("declare %1 binary cursor with hold for select %2")
+ .arg(cursorName).arg(quotedIdentifier(primaryKey));
- if (valid)
+ if(fetchGeometry)
{
+ declare += QString(",asbinary(%1,'%2') as qgs_feature_geometry")
+ .arg( quotedIdentifier(geometryColumn) )
+ .arg( endianString() );
+ }
- // Top up our queue if it is empty
- if (mFeatureQueue.empty())
+ QgsFieldMap attributeMap = fields();
+ for (QgsAttributeList::const_iterator it = fetchAttributes.constBegin(); it != fetchAttributes.constEnd(); ++it)
+ {
+ QgsFieldMap::const_iterator fieldIt = attributeMap.find(*it);
+ if(fieldIt != attributeMap.end())
{
- QString fetch = QString("fetch forward %1 from qgisf%2")
- .arg(mFeatureQueueSize)
- .arg(providerId);
+ const QString &fieldname = fieldIt.value().name();
- if(mFirstFetch)
+ if( fieldname != primaryKey )
{
- if(PQsendQuery(connection, fetch.toUtf8()) == 0) //fetch features in asynchronously
+ if( fieldIt.value().typeName() == "money" || fieldIt.value().typeName().startsWith("_") )
{
- qWarning("PQsendQuery failed (1)");
+ // money and arrays don't support cast to text, but return text
+ // TODO: check other types
+ declare += "," + quotedIdentifier( fieldname );
}
+ else if( fieldIt.value().typeName() == "bool" )
+ {
+ // bool doesn't support cast to text either and even doesn't return text.
+ // (even text() doesn't work with binary cursors)
+ declare += QString(",CASE WHEN %1 THEN 't' WHEN NOT %1 THEN 'f' ELSE NULL END AS %1")
+ .arg( quotedIdentifier(fieldname) );
+ }
+ else
+ {
+ declare += "," + quotedIdentifier( fieldname ) + "::text";
+ }
}
- mFirstFetch = false;
- queryResult = PQgetResult(connection);
- PQgetResult(connection); //just to get the 0 pointer...
- int rows = PQntuples(queryResult);
+ attributeNames << fieldname;
+ }
+ }
- if (rows == 0)
- {
- QgsDebugMsg("End of features");
+ declare += " from " + mSchemaTableName;
+
+ if( !whereClause.isEmpty() )
+ declare += QString(" where %1").arg(whereClause);
- PQclear(queryResult);
+ QgsDebugMsg("Binary cursor: " + declare);
- return false;
- }
+ PQexecNR(connection, declare.toUtf8());
+}
- for (int row = 0; row < rows; row++)
- {
- int oid = *(int *)PQgetvalue(queryResult, row, PQfnumber(queryResult,quotedIdentifier(primaryKey).toUtf8()));
+void QgsPostgresProvider::getFeature(PGresult *queryResult, int row, bool fetchGeometry,
+ QgsFeature &feature,
+ const QStringList &attributeNames,
+ const QgsAttributeList &fetchAttributes)
+{
+ int oid = *(int *)PQgetvalue(queryResult, row, PQfnumber(queryResult,quotedIdentifier(primaryKey).toUtf8()));
+ if (swapEndian)
+ oid = ntohl(oid); // convert oid to opposite endian
- if (swapEndian)
- oid = ntohl(oid); // convert oid to opposite endian
-
- mFeatureQueue.push(QgsFeature());
+ feature.setFeatureId(oid);
- // set ID
- mFeatureQueue.back().setFeatureId(oid);
+ // fetch attributes
+ QgsAttributeList::const_iterator it = fetchAttributes.constBegin();
+ for(QStringList::const_iterator namesIt = attributeNames.begin(); namesIt != attributeNames.end(); ++namesIt, ++it)
+ {
+ QString val;
- // fetch attributes
- std::list<QString>::const_iterator name_it = mFetchAttributeNames.begin();
- QgsAttributeList::const_iterator index_it = mAttributesToFetch.constBegin();
+ if( (*namesIt) == primaryKey)
+ {
+ val = QString::number(oid);
+ }
+ else
+ {
+ int fn = PQfnumber(queryResult,quotedIdentifier(*namesIt).toUtf8());
- for(; name_it != mFetchAttributeNames.end(); ++name_it, ++index_it)
- {
- QString val;
-
- if( (*name_it) == primaryKey)
- {
- val = QString::number(oid);
- }
- else
- {
- int fn = PQfnumber(queryResult,quotedIdentifier(*name_it).toUtf8());
-
- if( !PQgetisnull(queryResult, row, fn) )
- val = QString::fromUtf8(PQgetvalue(queryResult, row, fn));
- else
- val = QString::null;
- }
-
- if( val.isNull() )
- {
- mFeatureQueue.back().addAttribute(*index_it, val);
- }
- else
- {
- switch (attributeFields[*index_it].type())
- {
- case QVariant::LongLong:
- mFeatureQueue.back().addAttribute(*index_it, val.toLongLong());
- break;
- case QVariant::Int:
- mFeatureQueue.back().addAttribute(*index_it, val.toInt());
- break;
- case QVariant::Double:
- mFeatureQueue.back().addAttribute(*index_it, val.toDouble());
- break;
- case QVariant::String:
- mFeatureQueue.back().addAttribute(*index_it, val);
- break;
- default:
- assert(0 && "unsupported field type");
- }
- }
- }
-
- //fetch geometry
- if (mFetchGeom)
- {
- int returnedLength = PQgetlength(queryResult, row, PQfnumber(queryResult,"qgs_feature_geometry"));
- if(returnedLength > 0)
- {
- unsigned char *featureGeom = new unsigned char[returnedLength + 1];
- memset(featureGeom, '\0', returnedLength + 1);
- memcpy(featureGeom, PQgetvalue(queryResult, row, PQfnumber(queryResult,QString("qgs_feature_geometry").toUtf8())), returnedLength);
- mFeatureQueue.back().setGeometryAndOwnership(featureGeom, returnedLength + 1);
- }
- else
- {
- mFeatureQueue.back().setGeometryAndOwnership(0, 0);
- QgsDebugMsg("Couldn't get the feature geometry in binary form");
- }
- }
- } // for each row in queue
-
- PQclear(queryResult);
-
- if(PQsendQuery(connection, fetch.toUtf8()) == 0) //already fetch the next couple of features asynchronously
+ if( !PQgetisnull(queryResult, row, fn) )
{
- qWarning("PQsendQuery failed (2)");
+ val = QString::fromUtf8(PQgetvalue(queryResult, row, fn));
}
+ else
+ {
+ val = QString::null;
+ }
+ }
- } // if new queue is required
-
- // Now return the next feature from the queue
- if(mFetchGeom)
+ if( val.isNull() )
{
- QgsGeometry* featureGeom = mFeatureQueue.front().geometryAndOwnership();
- feature.setGeometry(featureGeom);
+ feature.addAttribute(*it, val);
}
else
{
- feature.setGeometryAndOwnership(0, 0);
+ switch (attributeFields[*it].type())
+ {
+ case QVariant::LongLong:
+ feature.addAttribute(*it, val.toLongLong());
+ break;
+ case QVariant::Int:
+ feature.addAttribute(*it, val.toInt());
+ break;
+ case QVariant::Double:
+ feature.addAttribute(*it, val.toDouble());
+ break;
+ case QVariant::String:
+ feature.addAttribute(*it, val);
+ break;
+ default:
+ assert(0 && "unsupported field type");
+ }
}
- feature.setFeatureId(mFeatureQueue.front().featureId());
- feature.setAttributeMap(mFeatureQueue.front().attributeMap());
-
- mFeatureQueue.pop();
-
}
- else
- {
- QgsDebugMsg("Read attempt on an invalid postgresql data source");
- return false;
- }
- return true;
-}
-
-void QgsPostgresProvider::select(QgsAttributeList fetchAttributes,
- QgsRect rect,
- bool fetchGeometry,
- bool useIntersect)
-{
- mFetchGeom = fetchGeometry;
- mAttributesToFetch = fetchAttributes;
-
- mFetchAttributeNames.clear();
- QgsFieldMap attributeMap = fields();
- QgsFieldMap::const_iterator fieldIt;
- for(QgsAttributeList::const_iterator it = mAttributesToFetch.constBegin();
- it != mAttributesToFetch.constEnd(); ++it)
+ if (fetchGeometry)
{
- fieldIt = attributeMap.find(*it);
- if(fieldIt != attributeMap.end())
+ int returnedLength = PQgetlength(queryResult, row, PQfnumber(queryResult,"qgs_feature_geometry"));
+ if(returnedLength > 0)
{
- mFetchAttributeNames.push_back(fieldIt.value().name());
+ unsigned char *featureGeom = new unsigned char[returnedLength + 1];
+ memset(featureGeom, '\0', returnedLength + 1);
+ memcpy(featureGeom, PQgetvalue(queryResult, row, PQfnumber(queryResult,QString("qgs_feature_geometry").toUtf8())), returnedLength);
+ feature.setGeometryAndOwnership(featureGeom, returnedLength + 1);
}
- }
+ else
+ {
+ feature.setGeometryAndOwnership(0, 0);
+ QgsDebugMsg("Couldn't get the feature geometry in binary form");
+ }
+ }
+}
+void QgsPostgresProvider::select(QgsAttributeList fetchAttributes, QgsRect rect, bool fetchGeometry, bool useIntersect)
+{
+ QString cursorName = QString("qgisf%1").arg(providerId);
+
if(mFetching)
{
- PQexecNR(connection, QString("CLOSE qgisf%1").arg(providerId).toUtf8() );
+ PQexecNR(connection, QString("CLOSE %1").arg(cursorName).toUtf8() );
mFetching=false;
- }
-
- QString declare = QString("declare qgisf%1 binary cursor with hold for select %2")
- .arg(providerId).arg(quotedIdentifier(primaryKey));
-
- if(fetchGeometry)
- {
- declare += QString(",asbinary(%1,'%2') as qgs_feature_geometry")
- .arg( quotedIdentifier(geometryColumn) )
- .arg( endianString() );
- }
-
- for(std::list<QString>::const_iterator it = mFetchAttributeNames.begin(); it != mFetchAttributeNames.end(); ++it)
- {
- if( (*it) != primaryKey) //no need to fetch primary key again
+
+ while(!mFeatureQueue.empty())
{
- declare += "," + quotedIdentifier(*it) + "::text";
+ mFeatureQueue.pop();
}
}
- declare += QString(" from %1").arg(mSchemaTableName);
+ QString whereClause;
- QgsDebugMsg("Binary cursor: " + declare);
-
- bool hasWhere = FALSE;
-
if(!rect.isEmpty())
{
if(useIntersect)
{
// Contributed by #qgis irc "creeping"
// This version actually invokes PostGIS's use of spatial indexes
- declare += " where " + quotedIdentifier(geometryColumn);
- declare += " && setsrid('BOX3D(" + rect.asWKTCoords();
- declare += ")'::box3d,";
- declare += srid;
- declare += ")";
- declare += " and intersects(" + quotedIdentifier(geometryColumn);
- declare += ", setsrid('BOX3D(" + rect.asWKTCoords();
- declare += ")'::box3d,";
- declare += srid;
- declare += "))";
+ whereClause = QString("%1 && setsrid('BOX3D(%2)'::box3d,%3) and intersects(%1,setsrid('BOX3D(%2)'::box3d,%3))")
+ .arg( quotedIdentifier(geometryColumn) )
+ .arg( rect.asWKTCoords() )
+ .arg( srid );
}
else
{
- declare += " where " + quotedIdentifier(geometryColumn);
- declare += " && setsrid('BOX3D(" + rect.asWKTCoords();
- declare += ")'::box3d,";
- declare += srid;
- declare += ")";
+ whereClause = QString("%1 && setsrid('BOX3D(%2)'::box3d,%3)")
+ .arg( quotedIdentifier(geometryColumn) )
+ .arg( rect.asWKTCoords() )
+ .arg( srid );
}
- hasWhere = TRUE;
}
- if(sqlWhereClause.length() > 0)
+ if( !sqlWhereClause.isEmpty() )
{
- if (hasWhere)
- declare += " and ";
- else
- declare += " where ";
- declare += "(" + sqlWhereClause + ")";
- hasWhere = TRUE;
- }
+ if (!whereClause.isEmpty())
+ whereClause += " and ";
- QgsDebugMsg("Selecting features using: " + declare);
-
- PQexecNR(connection, declare.toUtf8());
-
- while(!mFeatureQueue.empty())
- {
- mFeatureQueue.pop();
+ whereClause += "(" + sqlWhereClause + ")";
}
+ mFetchGeom = fetchGeometry;
+ mAttributesToFetch = fetchAttributes;
+ declareCursor( cursorName, fetchAttributes, fetchGeometry, whereClause, mFetchAttributeNames );
+
mFetching = true;
mFirstFetch = true;
}
-bool QgsPostgresProvider::getFeatureAtId(int featureId,
- QgsFeature& feature,
- bool fetchGeometry,
- QgsAttributeList fetchAttributes)
+bool QgsPostgresProvider::getNextFeature(QgsFeature& feature)
{
- std::list<QString> attributeNames;
- QgsFieldMap fldMap = fields();
- QgsFieldMap::const_iterator fieldIt;
- QgsAttributeList::const_iterator it;
- std::list<QString>::const_iterator namesIt;
+ QString cursorName = QString("qgisf%1").arg(providerId);
- for (it = fetchAttributes.constBegin(); it != fetchAttributes.constEnd(); ++it)
+ if (!valid)
{
- fieldIt = fldMap.find(*it);
- if(fieldIt != fldMap.end())
- {
- attributeNames.push_back(fieldIt.value().name());
- }
+ QgsDebugMsg("Read attempt on an invalid postgresql data source");
+ return false;
}
- QString declare = QString("declare qgisfid%1 binary cursor with hold for select %2")
- .arg(providerId).arg(quotedIdentifier(primaryKey));
-
- if(fetchGeometry)
+ // Top up our queue if it is empty
+ if (mFeatureQueue.empty())
{
- declare += QString(",asbinary(%1,'%2') as qgs_feature_geometry")
- .arg( quotedIdentifier(geometryColumn) )
- .arg( endianString() );
- }
+ QString fetch = QString("fetch forward %1 from %2").arg(mFeatureQueueSize).arg(cursorName);
+ if(mFirstFetch)
+ {
+ if(PQsendQuery(connection, fetch.toUtf8()) == 0) //fetch features in asynchronously
+ {
+ qWarning("PQsendQuery failed (1)");
+ }
+ }
+ mFirstFetch = false;
+ queryResult = PQgetResult(connection);
+ PQgetResult(connection); //just to get the 0 pointer...
- for(namesIt = attributeNames.begin(); namesIt != attributeNames.end(); ++namesIt)
- {
- if( (*namesIt) != primaryKey) //no need to fetch primary key again
+ int rows = PQntuples(queryResult);
+ if (rows == 0)
{
- declare += "," + quotedIdentifier(*namesIt) + "::text";
+ QgsDebugMsg("End of features");
+ PQclear(queryResult);
+ return false;
}
- }
- declare += QString(" from %1 where %2=%3")
- .arg(mSchemaTableName)
- .arg(quotedIdentifier(primaryKey))
- .arg(featureId);
+ for (int row = 0; row < rows; row++)
+ {
+ mFeatureQueue.push(QgsFeature());
+ getFeature(queryResult, row, mFetchGeom, mFeatureQueue.back(), mFetchAttributeNames, mAttributesToFetch);
+ } // for each row in queue
- QgsDebugMsg("Selecting feature using: " + declare);
+ PQclear(queryResult);
- // execute query
- PQexecNR(connection, declare.toUtf8());
+ if(PQsendQuery(connection, fetch.toUtf8()) == 0) //already fetch the next couple of features asynchronously
+ {
+ qWarning("PQsendQuery failed (2)");
+ }
+ } // if new queue is required
- PGresult *res = PQexec(connection, QString("fetch forward 1 from qgisfid%1").arg(providerId).toUtf8());
-
- int rows = PQntuples(res);
- if (rows == 0)
+ // Now return the next feature from the queue
+ if(mFetchGeom)
{
- PQclear(res);
- PQexecNR(connection, QString("CLOSE qgisfid%1").arg(providerId).toUtf8());
- QgsDebugMsg("feature " + QString::number(featureId) + " not found");
- return FALSE;
+ QgsGeometry* featureGeom = mFeatureQueue.front().geometryAndOwnership();
+ feature.setGeometry(featureGeom);
}
+ else
+ {
+ feature.setGeometryAndOwnership(0, 0);
+ }
+ feature.setFeatureId(mFeatureQueue.front().featureId());
+ feature.setAttributeMap(mFeatureQueue.front().attributeMap());
- // set ID
- int oid = *(int *)PQgetvalue(res, 0, PQfnumber(res,quotedIdentifier(primaryKey).toUtf8()));
- if (swapEndian)
- oid = ntohl(oid); // convert oid to opposite endian
- feature.setFeatureId(oid);
+ mFeatureQueue.pop();
- // fetch attributes
- it = fetchAttributes.constBegin();
+ return true;
+}
- for(namesIt = attributeNames.begin(); namesIt != attributeNames.end(); ++namesIt, ++it)
- {
- QString val;
+bool QgsPostgresProvider::getFeatureAtId(int featureId, QgsFeature& feature, bool fetchGeometry, QgsAttributeList fetchAttributes)
+{
+ QStringList attributeNames;
+ QString cursorName = QString("qgisfid%1").arg(providerId);
+ declareCursor( cursorName, fetchAttributes, fetchGeometry, QString("%2=%3").arg(quotedIdentifier(primaryKey)).arg(featureId), attributeNames );
- if( (*namesIt) == primaryKey)
- {
- val = QString::number(oid);
- }
- else
- {
- int fn = PQfnumber(res,quotedIdentifier(*namesIt).toUtf8());
+ PGresult *queryResult = PQexec(connection, QString("fetch forward 1 from %1").arg(cursorName).toUtf8());
+ if(queryResult==0)
+ return false;
- if( PQgetisnull(res, 0, fn) )
- val = QString::fromUtf8(PQgetvalue(res, 0, fn));
- else
- val = QString::null;
- }
-
- if( val.isNull() )
- {
- feature.addAttribute(*it, val);
- }
- else
- {
- switch (attributeFields[*it].type())
- {
- case QVariant::LongLong:
- feature.addAttribute(*it, val.toLongLong());
- break;
- case QVariant::Int:
- feature.addAttribute(*it, val.toInt());
- break;
- case QVariant::Double:
- feature.addAttribute(*it, val.toDouble());
- break;
- case QVariant::String:
- feature.addAttribute(*it, val);
- break;
- default:
- assert(0 && "unsupported field type");
- }
- }
+ int rows = PQntuples(queryResult);
+ if (rows == 0)
+ {
+ QgsDebugMsg("feature " + QString::number(featureId) + " not found");
+ PQclear(queryResult);
+ PQexecNR(connection, QString("CLOSE %1").arg(cursorName).toUtf8());
+ return false;
}
-
- // fetch geometry
- if (fetchGeometry)
+ else if(rows != 1)
{
- int returnedLength = PQgetlength(res, 0, PQfnumber(res,"qgs_feature_geometry"));
- if(returnedLength > 0)
- {
- unsigned char *featureGeom = new unsigned char[returnedLength + 1];
- memset(featureGeom, '\0', returnedLength + 1);
- memcpy(featureGeom, PQgetvalue(res, 0, PQfnumber(res,QString("qgs_feature_geometry").toUtf8())), returnedLength);
- feature.setGeometryAndOwnership(featureGeom, returnedLength + 1);
- }
+ QgsDebugMsg( QString("found %1 features instead of just one.").arg(rows) );
}
- PQclear(res);
- PQexecNR(connection, QString("CLOSE qgisfid%1").arg(providerId).toUtf8());
+ getFeature(queryResult, 0, fetchGeometry, feature, attributeNames, fetchAttributes);
- return TRUE;
+ PQclear(queryResult);
+
+ PQexecNR(connection, QString("CLOSE %1").arg(cursorName).toUtf8());
+ return true;
}
+
QgsDataSourceURI& QgsPostgresProvider::getURI()
{
return mUri;
@@ -891,16 +798,38 @@
if(fieldName!=geometryColumn)
{
QVariant::Type fieldType;
- if (fieldTypeName.find("int8") != -1)
+ bool isArray = fieldTypeName.startsWith("_");
+
+ if(isArray)
+ fieldTypeName = fieldTypeName.mid(1);
+
+ if (fieldTypeName == "int8" )
fieldType = QVariant::LongLong;
- else if (fieldTypeName.find("int") != -1 || fieldTypeName.find("serial") != -1)
+ else if (fieldTypeName.startsWith("int") || fieldTypeName=="serial" )
fieldType = QVariant::Int;
- else if (fieldTypeName == "real" || fieldTypeName == "double precision" || fieldTypeName.find("float") != -1)
+ else if (fieldTypeName == "real" || fieldTypeName == "double precision" || fieldTypeName.startsWith("float") || fieldTypeName == "numeric" )
fieldType = QVariant::Double;
- else if (fieldTypeName == "bytea")
- continue;
+ else if (fieldTypeName == "text" ||
+ fieldTypeName == "char" ||
+ fieldTypeName == "bpchar" ||
+ fieldTypeName == "varchar" ||
+ fieldTypeName == "bool" ||
+ fieldTypeName == "money" ||
+ fieldTypeName.startsWith("time") ||
+ fieldTypeName.startsWith("date") )
+ fieldType = QVariant::String;
else
+ {
+ QgsDebugMsg( "Field " + fieldName + " ignored, because of unsupported type " + fieldTypeName);
+ continue;
+ }
+
+ if(isArray)
+ {
+ fieldTypeName = "_" + fieldTypeName;
fieldType = QVariant::String;
+ }
+
attributeFields.insert(i, QgsField(fieldName, fieldType, fieldTypeName, fieldSize.toInt(), fieldModifier, fieldComment));
}
}
@@ -1653,11 +1582,16 @@
QString sql;
if(sqlWhereClause.isEmpty())
{
- sql = QString("select min(%1) from %2").arg(quotedIdentifier(fld.name())).arg(mSchemaTableName);
+ sql = QString("select min(%1) from %2")
+ .arg(quotedIdentifier(fld.name()))
+ .arg(mSchemaTableName);
}
else
{
- sql = QString("select min(%1) from %2").arg(quotedIdentifier(fld.name())).arg(mSchemaTableName)+" where "+sqlWhereClause;
+ sql = QString("select min(%1) from %2 where %3")
+ .arg(quotedIdentifier(fld.name()))
+ .arg(mSchemaTableName)
+ .arg(sqlWhereClause);
}
PGresult *rmin = PQexec(connection, sql.toUtf8());
QString minValue = QString::fromUtf8(PQgetvalue(rmin,0,0));
@@ -1705,11 +1639,16 @@
QString sql;
if(sqlWhereClause.isEmpty())
{
- sql = QString("select max(%1) from %2").arg(quotedIdentifier(fld.name())).arg(mSchemaTableName);
+ sql = QString("select max(%1) from %2")
+ .arg(quotedIdentifier(fld.name()))
+ .arg(mSchemaTableName);
}
else
{
- sql = QString("select max(%1) from %2").arg(quotedIdentifier(fld.name())).arg(mSchemaTableName)+" where "+sqlWhereClause;
+ sql = QString("select max(%1) from %2 where %3")
+ .arg(quotedIdentifier(fld.name()))
+ .arg(mSchemaTableName)
+ .arg(sqlWhereClause);
}
PGresult *rmax = PQexec(connection, sql.toUtf8());
QString maxValue = QString::fromUtf8(PQgetvalue(rmax,0,0));
@@ -1818,7 +1757,7 @@
useWkbHex = postgisVersionMajor < 1;
- gotPostgisVersion = TRUE;
+ gotPostgisVersion = true;
return postgisVersionInfo;
}
@@ -1872,7 +1811,7 @@
// e.g. for defaults
for(QgsAttributeMap::const_iterator it = attributevec.begin(); it != attributevec.end(); it++)
{
- QgsFieldMap::const_iterator fit = attributeFields.find( it.key() );
+ QgsFieldMap::const_iterator fit = attributeFields.find( it.key() );
if (fit == attributeFields.end() )
continue;
@@ -1897,7 +1836,7 @@
}
insert += "," + quotedIdentifier(fieldname);
-
+
QString defVal = getDefaultValue( it.key() ).toString();
if( i==flist.size() )
@@ -2685,8 +2624,7 @@
}
}
-void QgsPostgresProvider::showMessageBox(const QString& title,
- const QString& text)
+void QgsPostgresProvider::showMessageBox(const QString& title, const QString& text)
{
QgsMessageOutput* message = QgsMessageOutput::createMessageOutput();
message->setTitle(title);
Modified: trunk/qgis/src/providers/postgres/qgspostgresprovider.h
===================================================================
--- trunk/qgis/src/providers/postgres/qgspostgresprovider.h 2008-03-26 21:07:02 UTC (rev 8284)
+++ trunk/qgis/src/providers/postgres/qgspostgresprovider.h 2008-03-27 00:44:22 UTC (rev 8285)
@@ -110,6 +110,16 @@
bool fetchGeometry = true,
QgsAttributeList fetchAttributes = QgsAttributeList());
+ void declareCursor(const QString &cursorName,
+ const QgsAttributeList &fetchAttributes,
+ bool fetchGeometry,
+ QString whereClause,
+ QStringList &attributeNames);
+
+ void getFeature(PGresult *queryResult, int row, bool fetchGeometry,
+ QgsFeature &feature,
+ const QStringList &attributeNames,
+ const QgsAttributeList &fetchAttributes);
/** Get the feature type. This corresponds to
* WKBPoint,
@@ -444,7 +454,7 @@
bool swapEndian;
/**Stores the names of the attributes to fetch*/
- std::list<QString> mFetchAttributeNames;
+ QStringList mFetchAttributeNames;
bool deduceEndian();
bool getGeometryDetails();
More information about the QGIS-commit
mailing list