mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-25 00:58:06 -05:00
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:
parent
1f67699939
commit
d60680544c
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user