📄 qgspostgresprovider.cpp
字号:
// QgsDebugMsg( QString("defaultValue for %1 is NULL: %2").arg(fieldId).arg( defaultValue.isNull() ) ); PQclear(result); return defaultValue; } catch(PGFieldNotFound) { return QVariant(QString::null); }}/** * Check to see if GEOS is available */bool QgsPostgresProvider::hasGEOS(PGconn *connection){ // make sure info is up to date for the current connection postgisVersion(connection); // get geos capability return geosAvailable;}/* Functions for determining available features in postGIS */QString QgsPostgresProvider::postgisVersion(PGconn *connection){ PGresult *result = PQexec(connection, QString("select postgis_version()").toUtf8()); postgisVersionInfo = QString::fromUtf8(PQgetvalue(result,0,0)); QgsDebugMsg("PostGIS version info: " + postgisVersionInfo); PQclear(result); QStringList postgisParts = QStringList::split(" ", postgisVersionInfo); // Get major and minor version QStringList postgisVersionParts = QStringList::split(".", postgisParts[0]); postgisVersionMajor = postgisVersionParts[0].toInt(); postgisVersionMinor = postgisVersionParts[1].toInt(); // assume no capabilities geosAvailable = false; gistAvailable = false; projAvailable = false; // parse out the capabilities and store them QStringList geos = postgisParts.grep("GEOS"); if(geos.size() == 1) { geosAvailable = (geos[0].find("=1") > -1); } QStringList gist = postgisParts.grep("STATS"); if(gist.size() == 1) { gistAvailable = (geos[0].find("=1") > -1); } QStringList proj = postgisParts.grep("PROJ"); if(proj.size() == 1) { projAvailable = (proj[0].find("=1") > -1); } useWkbHex = postgisVersionMajor < 1; gotPostgisVersion = true; return postgisVersionInfo;}QByteArray QgsPostgresProvider::paramValue(QString fieldValue, const QString &defaultValue) const{ if( fieldValue.isNull() ) return QByteArray(0); // QByteArray(0).isNull() is true if( fieldValue==defaultValue && !defaultValue.isNull() ) { PGresult *result = PQexec( connection, QString("select %1").arg(defaultValue).toUtf8() ); if( PQgetisnull(result, 0, 0) ) { PQclear(result); return QByteArray(0); // QByteArray(0).isNull() is true } else { QString val = QString::fromUtf8(PQgetvalue(result,0,0)); PQclear(result); return val.toUtf8(); } } return fieldValue.toUtf8();}bool QgsPostgresProvider::addFeatures(QgsFeatureList & flist){ if( flist.size() == 0 ) return true; bool returnvalue=true; try { PQexecNR(connection,QString("BEGIN").toUtf8()); // Prepare the INSERT statement QString insert = QString("INSERT INTO %1(%2,%3") .arg( mSchemaTableName ) .arg( quotedIdentifier(geometryColumn) ) .arg( quotedIdentifier(primaryKey) ), values = QString(") VALUES (GeomFromWKB($1%1,%2),$2") .arg( useWkbHex ? "" : "::bytea" ) .arg( srid ); const QgsAttributeMap &attributevec = flist[0].attributeMap(); QStringList defaultValue; QList<int> fieldId; // look for unique attribute values to place in statement instead of passing as parameter // e.g. for defaults for(QgsAttributeMap::const_iterator it = attributevec.begin(); it != attributevec.end(); it++) { QgsFieldMap::const_iterator fit = attributeFields.find( it.key() ); if (fit == attributeFields.end() ) continue; QString fieldname = fit->name(); QgsDebugMsg("Checking field against: " + fieldname); if( fieldname.isEmpty() || fieldname==geometryColumn || fieldname==primaryKey ) continue; int i; for(i=1; i<flist.size(); i++) { const QgsAttributeMap &attributevec = flist[i].attributeMap(); QgsAttributeMap::const_iterator thisit = attributevec.find( it.key() ); if( thisit == attributevec.end() ) break; if( *thisit!=*it ) break; } insert += "," + quotedIdentifier(fieldname); QString defVal = getDefaultValue( it.key() ).toString(); if( i==flist.size() ) { if( !defVal.isNull() && *it==defVal) { values += "," + defVal; } else { values += "," + quotedValue( it->toString() ); } } else { // value is not unique => add parameter values += QString(",$%1").arg( defaultValue.size()+3 ); defaultValue.append( defVal ); fieldId.append( it.key() ); } } insert += values + ")"; PGresult *stmt = PQprepare(connection, "addfeatures", insert.toUtf8(), fieldId.size()+2, NULL); if(stmt==0 || PQresultStatus(stmt)==PGRES_FATAL_ERROR) throw PGException(stmt); PQclear(stmt); int primaryKeyHighWater = maxPrimaryKeyValue(); const char **param = new const char *[ fieldId.size()+2 ]; for(QgsFeatureList::iterator features=flist.begin(); features!=flist.end(); features++) { const QgsAttributeMap &attributevec = features->attributeMap(); QString geomParam; appendGeomString( features->geometry(), geomParam); QList<QByteArray> qparam; qparam.append( geomParam.toUtf8() ); qparam.append( QString("%1").arg( ++primaryKeyHighWater ).toUtf8() ); param[0] = qparam[0]; param[1] = qparam[1]; for(int i=0; i<fieldId.size(); i++) { qparam.append( paramValue( attributevec[ fieldId[i] ].toString(), defaultValue[i] ) ); if( qparam[i+2].isNull() ) param[i+2] = 0; else param[i+2] = qparam[i+2]; } PGresult *result = PQexecPrepared(connection, "addfeatures", fieldId.size()+2, param, NULL, NULL, 0); if( result==0 || PQresultStatus(result)==PGRES_FATAL_ERROR ) { delete param; throw PGException(result); } PQclear(result); } PQexecNR(connection,QString("COMMIT").toUtf8()); PQexecNR(connection,QString("DEALLOCATE addfeatures").toUtf8()); delete param; } catch(PGException &e) { e.showErrorMessage( tr("Error while adding features") ); PQexecNR(connection,QString("ROLLBACK").toUtf8()); PQexecNR(connection,QString("DEALLOCATE addfeatures").toUtf8()); returnvalue = false; } reset(); return returnvalue;}bool QgsPostgresProvider::deleteFeatures(const QgsFeatureIds & id){ bool returnvalue=true; try { PQexecNR(connection,QString("BEGIN").toUtf8()); for(QgsFeatureIds::const_iterator it=id.begin();it!=id.end();++it) { QString sql = QString("DELETE FROM %1 WHERE %2=%3") .arg(mSchemaTableName) .arg(quotedIdentifier(primaryKey)) .arg(*it); QgsDebugMsg("delete sql: "+sql); //send DELETE statement and do error handling PGresult* result=PQexec(connection, sql.toUtf8()); if( result==0 || PQresultStatus(result)==PGRES_FATAL_ERROR ) throw PGException(result); PQclear(result); } PQexecNR(connection,QString("COMMIT").toUtf8()); } catch(PGException &e) { e.showErrorMessage( tr("Error while deleting features") ); PQexecNR(connection,QString("ROLLBACK").toUtf8()); returnvalue = false; } reset(); return returnvalue;}bool QgsPostgresProvider::addAttributes(const QgsNewAttributesMap & name){ bool returnvalue=true; try { PQexecNR(connection,QString("BEGIN").toUtf8()); for(QgsNewAttributesMap::const_iterator iter=name.begin();iter!=name.end();++iter) { QString sql = QString("ALTER TABLE %1 ADD COLUMN %2 %3") .arg(mSchemaTableName) .arg(quotedIdentifier(iter.key())) .arg(iter.value()); QgsDebugMsg(sql); //send sql statement and do error handling PGresult* result=PQexec(connection, sql.toUtf8()); if( result==0 || PQresultStatus(result)==PGRES_FATAL_ERROR ) throw PGException(result); PQclear(result); } PQexecNR(connection,QString("COMMIT").toUtf8()); } catch(PGException &e) { e.showErrorMessage( tr("Error while adding attributes") ); PQexecNR(connection,QString("ROLLBACK").toUtf8()); returnvalue = false; } reset(); return returnvalue;}bool QgsPostgresProvider::deleteAttributes(const QgsAttributeIds& ids){ bool returnvalue=true; try { PQexecNR(connection,QString("BEGIN").toUtf8()); for(QgsAttributeIds::const_iterator iter=ids.begin();iter != ids.end();++iter) { QgsFieldMap::const_iterator field_it = attributeFields.find(*iter); if(field_it == attributeFields.constEnd()) continue; QString column = field_it->name(); QString sql = QString("ALTER TABLE %1 DROP COLUMN %2") .arg(mSchemaTableName) .arg(quotedIdentifier(column)); //send sql statement and do error handling PGresult* result=PQexec(connection, sql.toUtf8()); if( result==0 || PQresultStatus(result)==PGRES_FATAL_ERROR ) throw PGException(result); PQclear(result); //delete the attribute from attributeFields attributeFields.remove(*iter); } PQexecNR(connection,QString("COMMIT").toUtf8()); } catch(PGException &e) { e.showErrorMessage( tr("Error while deleting attributes") ); PQexecNR(connection,QString("ROLLBACK").toUtf8()); returnvalue = false; } reset(); return returnvalue;}bool QgsPostgresProvider::changeAttributeValues(const QgsChangedAttributesMap & attr_map){ bool returnvalue=true; try { PQexecNR(connection,QString("BEGIN").toUtf8()); // cycle through the features for(QgsChangedAttributesMap::const_iterator iter=attr_map.begin();iter!=attr_map.end();++iter) { int fid = iter.key(); // skip added features if(fid<0) continue; QString sql = QString("UPDATE %1 SET ").arg( mSchemaTableName ); bool first = true; const QgsAttributeMap& attrs = iter.value(); // cycle through the changed attributes of the feature for(QgsAttributeMap::const_iterator siter = attrs.begin(); siter != attrs.end(); ++siter) { try { QString fieldName = field(siter.key()).name(); if(!first) sql += ","; else first=false; sql += QString("%1=%2") .arg( quotedIdentifier(fieldName) ) .arg( quotedValue( siter->toString() ) ); } catch(PGFieldNotFound) { // Field was missing - shouldn't happen } } sql += QString(" WHERE %1=%2") .arg( quotedIdentifier(primaryKey) ) .arg( fid ); PGresult* result=PQexec(connection, sql.toUtf8()); if( result==0 || PQresultStatus(result)==PGRES_FATAL_ERROR ) throw PGException(result); PQclear(result); } PQexecNR(connection,QString("COMMIT").toUtf8()); } catch(PGException &e) { e.showErrorMessage( tr("Error while changing attributes") ); PQexecNR(connection,QString("ROLLBACK").toUtf8()); returnvalue = false; } reset(); return returnvalue;}void QgsPostgresProvider::appendGeomString(QgsGeometry *geom, QString &geomString) const{ unsigned char *buf = geom->wkbBuffer(); for (uint i=0; i < geom->wkbSize(); ++i) { if (useWkbHex) geomString += QString("%1").arg( (int) buf[i], 2, 16, QChar('0')); else geomString += QString("\\%1").arg( (int) buf[i], 3, 8, QChar('0')); }}bool QgsPostgresProvider::changeGeometryValues(QgsGeometryMap & geometry_map){ QgsDebugMsg("entering."); bool returnvalue = true; try { // Start the PostGIS transaction PQexecNR(connection,QString("BEGIN").toUtf8()); QString update = QString("UPDATE %1 SET %2=GeomFromWKB($1%3,%4) WHERE %5=$2")
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -