added validity checking at the data provider level. Modified logging in postgres provider

git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@591 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
gsherman 2004-01-25 07:41:36 +00:00
parent 1f67699939
commit d60680544c
4 changed files with 46 additions and 19 deletions

View File

@ -352,7 +352,12 @@ void QgsShapeFileProvider::fillMinMaxCash()
minmaxcachedirty=false; minmaxcachedirty=false;
} }
//TODO - add sanity check for shape file layers, to include cheking to
// see if the .shp, .dbf, .shx files are all present and the layer
// actually has features
bool QgsShapeFileProvider::isValid(){
return true;
}
/** /**
* Class factory to return a pointer to a newly created * Class factory to return a pointer to a newly created
* QgsShapeFileProvider object * QgsShapeFileProvider object

View File

@ -113,6 +113,11 @@ public:
/**Returns the maximum value of an attribut /**Returns the maximum value of an attribut
@param position the number of the attribute*/ @param position the number of the attribute*/
QString maxValue(int position); QString maxValue(int position);
/**Returns true if this is a valid shapefile
*/
bool isValid();
private: private:
unsigned char *getGeometryPointer(OGRFeature *fet); unsigned char *getGeometryPointer(OGRFeature *fet);
std::vector<QgsFeature> features; std::vector<QgsFeature> features;

View File

@ -27,6 +27,8 @@
#include "qgspostgresprovider.h" #include "qgspostgresprovider.h"
QgsPostgresProvider::QgsPostgresProvider(QString uri):dataSourceUri(uri) QgsPostgresProvider::QgsPostgresProvider(QString uri):dataSourceUri(uri)
{ {
// assume this is a valid layer until we determine otherwise
valid = true;
/* OPEN LOG FILE */ /* OPEN LOG FILE */
// make connection to the data source // make connection to the data source
@ -52,13 +54,16 @@ QgsPostgresProvider::QgsPostgresProvider(QString uri):dataSourceUri(uri)
qWarning("Geometry column is: " + geometryColumn); qWarning("Geometry column is: " + geometryColumn);
qWarning("Schema is: " + schema); qWarning("Schema is: " + schema);
qWarning("Table name is: " + tableName); qWarning("Table name is: " + tableName);
QString logFile = "./pg_provider_" + tableName + ".log"; //QString logFile = "./pg_provider_" + tableName + ".log";
pLog.open((const char *)logFile); //pLog.open((const char *)logFile);
pLog << "Opened log file for " << tableName << std::endl; std::cerr << "Opened log file for " << tableName << std::endl;
PGconn *pd = PQconnectdb((const char *) connInfo); PGconn *pd = PQconnectdb((const char *) connInfo);
// check the connection status // check the connection status
if (PQstatus(pd) == CONNECTION_OK) { if (PQstatus(pd) == CONNECTION_OK) {
//--std::cout << "Connection to the database was successful\n"; //--std::cout << "Connection to the database was successful\n";
// set the schema
PQexec(pd,(const char *)QString("set search_path = '%1','public'").arg(schema));
// store the connection for future use // store the connection for future use
connection = pd; connection = pd;
// check the geometry column // check the geometry column
@ -84,13 +89,16 @@ QgsPostgresProvider::QgsPostgresProvider(QString uri):dataSourceUri(uri)
PGresult * oidResult = PQexec(pd, firstOid); PGresult * oidResult = PQexec(pd, firstOid);
// get the int value from a "normal" select // get the int value from a "normal" select
QString oidValue = PQgetvalue(oidResult,0,0); QString oidValue = PQgetvalue(oidResult,0,0);
std::cerr << "Creating binary cursor" << std::endl;
// get the same value using a binary cursor // get the same value using a binary cursor
PQexec(pd,"begin work"); PQexec(pd,"begin work");
QString oidDeclare = QString("declare oidcursor binary cursor for select oid from %1 where oid = %2").arg(tableName).arg(oidValue); QString oidDeclare = QString("declare oidcursor binary cursor for select oid from %1 where oid = %2").arg(tableName).arg(oidValue);
// set up the cursor // set up the cursor
PQexec(pd, (const char *)oidDeclare); PQexec(pd, (const char *)oidDeclare);
QString fetch = "fetch forward 1 from oidcursor"; QString fetch = "fetch forward 1 from oidcursor";
std::cerr << "Fecthing a record and attempting to get check endian-ness" << std::endl;
PGresult *fResult = PQexec(pd, (const char *)fetch); PGresult *fResult = PQexec(pd, (const char *)fetch);
if(PQntuples(fResult) > 0){
// get the oid value from the binary cursor // get the oid value from the binary cursor
int oid = *(int *)PQgetvalue(fResult,0,0); int oid = *(int *)PQgetvalue(fResult,0,0);
@ -104,7 +112,7 @@ QgsPostgresProvider::QgsPostgresProvider(QString uri):dataSourceUri(uri)
} }
// end the cursor transaction // end the cursor transaction
PQexec(pd, "end work"); PQexec(pd, "end work");
std::cerr << "Setting layer type" << std::endl;
// set the type // set the type
// set the simple type for use with symbology operations // set the simple type for use with symbology operations
QString fType = PQgetvalue(result, 0, PQfnumber(result, "type")); QString fType = PQgetvalue(result, 0, PQfnumber(result, "type"));
@ -192,11 +200,16 @@ QgsPostgresProvider::QgsPostgresProvider(QString uri):dataSourceUri(uri)
sql = "select count(*) from " + tableName; sql = "select count(*) from " + tableName;
result = PQexec(pd, (const char *) sql); result = PQexec(pd, (const char *) sql);
numberFeatures = QString(PQgetvalue(result, 0, 0)).toLong(); numberFeatures = QString(PQgetvalue(result, 0, 0)).toLong();
pLog << "Number of features: " << numberFeatures << std::endl; std::cerr << "Number of features: " << numberFeatures << std::endl;
//--std::cout << "Number of features in " << (const char *) tableName << ": " << numberFeatures << std::endl;
}else{
numberFeatures = 0;
valid = false;
}//--std::cout << "Number of features in " << (const char *) tableName << ": " << numberFeatures << std::endl;
} else { } else {
// the table is not a geometry table // the table is not a geometry table
valid = false; valid = false;
std::cerr << "Invalid Postgres layer" << std::endl;
} }
// reset tableName to include schema // reset tableName to include schema
schemaTableName += schema + "." + tableName; schemaTableName += schema + "." + tableName;
@ -222,7 +235,7 @@ QgsPostgresProvider::QgsPostgresProvider(QString uri):dataSourceUri(uri)
QgsPostgresProvider::~QgsPostgresProvider() QgsPostgresProvider::~QgsPostgresProvider()
{ {
pLog.flush(); //pLog.flush();
} }
//TODO - we may not need this function - consider removing it from //TODO - we may not need this function - consider removing it from
@ -478,7 +491,7 @@ void QgsPostgresProvider::reset()
primaryKey + primaryKey +
",asbinary(%1,'%2') as qgs_feature_geometry from %3").arg(geometryColumn).arg(endianString()).arg(tableName); ",asbinary(%1,'%2') as qgs_feature_geometry from %3").arg(geometryColumn).arg(endianString()).arg(tableName);
//--std::cout << "Selecting features using: " << declare << std::endl; //--std::cout << "Selecting features using: " << declare << std::endl;
pLog << "Setting up binary cursor: " << declare << std::endl; std::cerr << "Setting up binary cursor: " << declare << std::endl;
// set up the cursor // set up the cursor
PQexec(connection,"end work"); PQexec(connection,"end work");
PQexec(connection,"begin work"); PQexec(connection,"begin work");
@ -518,22 +531,22 @@ QString QgsPostgresProvider::endianString()
} }
QString QgsPostgresProvider::getPrimaryKey(){ QString QgsPostgresProvider::getPrimaryKey(){
QString sql = "select oid from pg_class where relname = '" + tableName + "'"; QString sql = "select oid from pg_class where relname = '" + tableName + "'";
pLog << "Getting primary key" << std::endl; std::cerr << "Getting primary key" << std::endl;
pLog << sql << std::endl; std::cerr << sql << std::endl;
PGresult *pk = PQexec(connection,(const char *)sql); PGresult *pk = PQexec(connection,(const char *)sql);
pLog << "Got " << PQntuples(pk) << " rows " << std::endl; std::cerr << "Got " << PQntuples(pk) << " rows " << std::endl;
// get the oid for the table // get the oid for the table
QString oid = PQgetvalue(pk,0,0); QString oid = PQgetvalue(pk,0,0);
// check to see if there is a primary key // check to see if there is a primary key
sql = "select indkey from pg_index where indrelid = " + sql = "select indkey from pg_index where indrelid = " +
oid + " and indisprimary = 't'"; oid + " and indisprimary = 't'";
pLog << sql << std::endl; std::cerr << sql << std::endl;
PQclear(pk); PQclear(pk);
pk = PQexec(connection,(const char *)sql); pk = PQexec(connection,(const char *)sql);
// if we got no tuples we ain't go no pk :) // if we got no tuples we ain't go no pk :)
if(PQntuples(pk) == 0){ if(PQntuples(pk) == 0){
// no key - should we warn the user that performance will suffer // no key - should we warn the user that performance will suffer
pLog << "Table has no primary key -- using oid to fetch records" << std::endl; std::cerr << "Table has no primary key -- using oid to fetch records" << std::endl;
primaryKey = "oid"; primaryKey = "oid";
}else{ }else{
// store the key column // store the key column
@ -541,13 +554,13 @@ QString QgsPostgresProvider::getPrimaryKey(){
QStringList columns = QStringList::split(" ", keyString); QStringList columns = QStringList::split(" ", keyString);
if(columns.count() > 1){ if(columns.count() > 1){
//TODO concatenated key -- can we use this? //TODO concatenated key -- can we use this?
pLog << "Table has a concatenated primary key" << std::endl; std::cerr << "Table has a concatenated primary key" << std::endl;
} }
primaryKeyIndex = columns[0].toInt()-1; primaryKeyIndex = columns[0].toInt()-1;
QgsField fld = attributeFields[primaryKeyIndex]; QgsField fld = attributeFields[primaryKeyIndex];
primaryKey = fld.getName(); primaryKey = fld.getName();
pLog << "Primary key is " << primaryKey << std::endl;//);// +<< " at column " << primaryKeyIndex << std::endl; std::cerr << "Primary key is " << primaryKey << std::endl;//);// +<< " at column " << primaryKeyIndex << std::endl;
pLog.flush(); // pLog.flush();
} }
PQclear(pk); PQclear(pk);
return primaryKey; return primaryKey;
@ -592,7 +605,9 @@ QString QgsPostgresProvider::maxValue(int position){
return maxValue; return maxValue;
} }
bool QgsPostgresProvider::isValid(){
return valid;
}
/** /**
* Class factory to return a pointer to a newly created * Class factory to return a pointer to a newly created
* QgsPostgresProvider object * QgsPostgresProvider object

View File

@ -141,7 +141,9 @@ class QgsPostgresProvider:public QgsDataProvider
/**Returns the maximum value of an attributs /**Returns the maximum value of an attributs
@param position the number of the attribute*/ @param position the number of the attribute*/
QString maxValue(int position); QString maxValue(int position);
/**Returns true if layer is valid
*/
bool isValid();
private: private:
std::vector < QgsFeature > features; std::vector < QgsFeature > features;
std::vector < bool > *selected; std::vector < bool > *selected;