Skip to content

Commit a4cf54a

Browse files
author
wonder
committedApr 17, 2007
Slightly better error handling in constructor of postgres provider
git-svn-id: http://svn.osgeo.org/qgis/trunk@6892 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 0dc4a3b commit a4cf54a

File tree

1 file changed

+164
-163
lines changed

1 file changed

+164
-163
lines changed
 

‎src/providers/postgres/qgspostgresprovider.cpp

Lines changed: 164 additions & 163 deletions
Original file line numberDiff line numberDiff line change
@@ -112,186 +112,187 @@ QgsPostgresProvider::QgsPostgresProvider(QString const & uri)
112112

113113
PGconn *pd = PQconnectdb((const char *) mUri.connInfo);
114114
// check the connection status
115-
if (PQstatus(pd) == CONNECTION_OK)
115+
if (PQstatus(pd) != CONNECTION_OK)
116116
{
117-
// store the connection for future use
118-
connection = pd;
117+
QgsDebugMsg("Connection to database failed");
118+
valid = false;
119+
return;
120+
}
121+
122+
// store the connection for future use
123+
connection = pd;
119124

120-
//set client encoding to unicode because QString uses UTF-8 anyway
121-
QgsDebugMsg("setting client encoding to UNICODE");
122-
123-
int errcode=PQsetClientEncoding(connection, "UNICODE");
124-
125-
if(errcode==0) {
126-
QgsDebugMsg("encoding successfully set");
127-
} else if(errcode==-1) {
128-
QgsDebugMsg("error in setting encoding");
129-
} else {
130-
QgsDebugMsg("undefined return value from encoding setting");
131-
}
125+
//set client encoding to unicode because QString uses UTF-8 anyway
126+
QgsDebugMsg("setting client encoding to UNICODE");
127+
128+
int errcode=PQsetClientEncoding(connection, "UNICODE");
129+
130+
if(errcode==0) {
131+
QgsDebugMsg("encoding successfully set");
132+
} else if(errcode==-1) {
133+
QgsDebugMsg("error in setting encoding");
134+
} else {
135+
QgsDebugMsg("undefined return value from encoding setting");
136+
}
132137

133-
QgsDebugMsg("Checking for select permission on the relation\n");
134-
135-
// Check that we can read from the table (i.e., we have
136-
// select permission).
137-
QString sql = "select * from " + mSchemaTableName + " limit 1";
138-
PGresult* testAccess = PQexec(pd, (const char*)(sql.utf8()));
139-
if (PQresultStatus(testAccess) != PGRES_TUPLES_OK)
140-
{
141-
showMessageBox(tr("Unable to access relation"),
142-
tr("Unable to access the ") + mSchemaTableName +
143-
tr(" relation.\nThe error message from the database was:\n") +
144-
QString(PQresultErrorMessage(testAccess)) + ".\n" +
145-
"SQL: " + sql);
146-
PQclear(testAccess);
147-
valid = false;
148-
return;
149-
}
138+
QgsDebugMsg("Checking for select permission on the relation\n");
139+
140+
// Check that we can read from the table (i.e., we have
141+
// select permission).
142+
QString sql = "select * from " + mSchemaTableName + " limit 1";
143+
PGresult* testAccess = PQexec(pd, (const char*)(sql.utf8()));
144+
if (PQresultStatus(testAccess) != PGRES_TUPLES_OK)
145+
{
146+
showMessageBox(tr("Unable to access relation"),
147+
tr("Unable to access the ") + mSchemaTableName +
148+
tr(" relation.\nThe error message from the database was:\n") +
149+
QString(PQresultErrorMessage(testAccess)) + ".\n" +
150+
"SQL: " + sql);
150151
PQclear(testAccess);
152+
valid = false;
153+
PQfinish(connection);
154+
return;
155+
}
156+
PQclear(testAccess);
151157

152-
/* Check to see if we have GEOS support and if not, warn the user about
153-
the problems they will see :) */
154-
QgsDebugMsg("Checking for GEOS support");
158+
/* Check to see if we have GEOS support and if not, warn the user about
159+
the problems they will see :) */
160+
QgsDebugMsg("Checking for GEOS support");
155161

156-
if(!hasGEOS(pd))
157-
{
158-
showMessageBox(tr("No GEOS Support!"),
159-
tr("Your PostGIS installation has no GEOS support.\n"
160-
"Feature selection and identification will not "
161-
"work properly.\nPlease install PostGIS with "
162-
"GEOS support (http://geos.refractions.net)"));
163-
}
164-
//--std::cout << "Connection to the database was successful\n";
162+
if(!hasGEOS(pd))
163+
{
164+
showMessageBox(tr("No GEOS Support!"),
165+
tr("Your PostGIS installation has no GEOS support.\n"
166+
"Feature selection and identification will not "
167+
"work properly.\nPlease install PostGIS with "
168+
"GEOS support (http://geos.refractions.net)"));
169+
}
170+
//--std::cout << "Connection to the database was successful\n";
165171

166-
if (getGeometryDetails()) // gets srid and geometry type
172+
if (!getGeometryDetails()) // gets srid and geometry type
173+
{
174+
// the table is not a geometry table
175+
numberFeatures = 0;
176+
valid = false;
177+
178+
QgsDebugMsg("Invalid Postgres layer");
179+
PQfinish(connection);
180+
return;
181+
}
182+
183+
deduceEndian();
184+
calculateExtents();
185+
getFeatureCount();
186+
187+
// Get the relation oid for use in later queries
188+
sql = "SELECT oid FROM pg_class WHERE relname = '" + mTableName + "' AND relnamespace = ("
189+
"SELECT oid FROM pg_namespace WHERE nspname = '" + mSchemaName + "')";
190+
PGresult *tresult= PQexec(pd, (const char *)(sql.utf8()));
191+
QString tableoid = PQgetvalue(tresult, 0, 0);
192+
PQclear(tresult);
193+
194+
// Get the table description
195+
sql = "SELECT description FROM pg_description WHERE "
196+
"objoid = " + tableoid + " AND objsubid = 0";
197+
tresult = PQexec(pd, (const char*) sql.utf8());
198+
if (PQntuples(tresult) > 0)
199+
mDataComment = PQgetvalue(tresult, 0, 0);
200+
PQclear(tresult);
201+
202+
// Populate the field vector for this layer. The field vector contains
203+
// field name, type, length, and precision (if numeric)
204+
sql = "select * from " + mSchemaTableName + " limit 0";
205+
206+
PGresult *result = PQexec(pd, (const char *) (sql.utf8()));
207+
//--std::cout << "Field: Name, Type, Size, Modifier:" << std::endl;
208+
209+
// The queries inside this loop could possibly be combined into one
210+
// single query - this would make the code run faster.
211+
212+
for (int i = 0; i < PQnfields(result); i++)
213+
{
214+
QString fieldName = PQfname(result, i);
215+
int fldtyp = PQftype(result, i);
216+
QString typOid = QString().setNum(fldtyp);
217+
int fieldModifier = PQfmod(result, i);
218+
QString fieldComment("");
219+
220+
sql = "SELECT typname, typlen FROM pg_type WHERE "
221+
"oid = (SELECT typelem FROM pg_type WHERE "
222+
"typelem = " + typOid + " AND typlen = -1)";
223+
224+
PGresult* oidResult = PQexec(pd, (const char *) sql);
225+
QString fieldTypeName = PQgetvalue(oidResult, 0, 0);
226+
QString fieldSize = PQgetvalue(oidResult, 0, 1);
227+
PQclear(oidResult);
228+
229+
sql = "SELECT attnum FROM pg_attribute WHERE "
230+
"attrelid = " + tableoid + " AND attname = '" + fieldName + "'";
231+
PGresult *tresult = PQexec(pd, (const char *)(sql.utf8()));
232+
QString attnum = PQgetvalue(tresult, 0, 0);
233+
PQclear(tresult);
234+
235+
sql = "SELECT description FROM pg_description WHERE "
236+
"objoid = " + tableoid + " AND objsubid = " + attnum;
237+
tresult = PQexec(pd, (const char*)(sql.utf8()));
238+
if (PQntuples(tresult) > 0)
239+
fieldComment = PQgetvalue(tresult, 0, 0);
240+
PQclear(tresult);
241+
242+
QgsDebugMsg("Field: " + attnum + " maps to " + QString::number(i) + " " + fieldName + ", "
243+
+ fieldTypeName + " (" + QString::number(fldtyp) + "), " + fieldSize + ", " + QString::number(fieldModifier));
244+
245+
attributeFieldsIdMap[attnum.toInt()] = i;
246+
247+
if(fieldName!=geometryColumn)
167248
{
168-
deduceEndian();
169-
calculateExtents();
170-
getFeatureCount();
171-
172-
// Get the relation oid for use in later queries
173-
sql = "SELECT oid FROM pg_class WHERE relname = '" + mTableName + "' AND relnamespace = ("
174-
"SELECT oid FROM pg_namespace WHERE nspname = '" + mSchemaName + "')";
175-
PGresult *tresult= PQexec(pd, (const char *)(sql.utf8()));
176-
QString tableoid = PQgetvalue(tresult, 0, 0);
177-
PQclear(tresult);
178-
179-
// Get the table description
180-
sql = "SELECT description FROM pg_description WHERE "
181-
"objoid = " + tableoid + " AND objsubid = 0";
182-
tresult = PQexec(pd, (const char*) sql.utf8());
183-
if (PQntuples(tresult) > 0)
184-
mDataComment = PQgetvalue(tresult, 0, 0);
185-
PQclear(tresult);
186-
187-
// Populate the field vector for this layer. The field vector contains
188-
// field name, type, length, and precision (if numeric)
189-
sql = "select * from " + mSchemaTableName + " limit 0";
190-
191-
PGresult *result = PQexec(pd, (const char *) (sql.utf8()));
192-
//--std::cout << "Field: Name, Type, Size, Modifier:" << std::endl;
193-
194-
// The queries inside this loop could possibly be combined into one
195-
// single query - this would make the code run faster.
196-
197-
for (int i = 0; i < PQnfields(result); i++)
198-
{
199-
QString fieldName = PQfname(result, i);
200-
int fldtyp = PQftype(result, i);
201-
QString typOid = QString().setNum(fldtyp);
202-
int fieldModifier = PQfmod(result, i);
203-
QString fieldComment("");
204-
205-
sql = "SELECT typname, typlen FROM pg_type WHERE "
206-
"oid = (SELECT typelem FROM pg_type WHERE "
207-
"typelem = " + typOid + " AND typlen = -1)";
208-
209-
PGresult* oidResult = PQexec(pd, (const char *) sql);
210-
QString fieldTypeName = PQgetvalue(oidResult, 0, 0);
211-
QString fieldSize = PQgetvalue(oidResult, 0, 1);
212-
PQclear(oidResult);
213-
214-
sql = "SELECT attnum FROM pg_attribute WHERE "
215-
"attrelid = " + tableoid + " AND attname = '" + fieldName + "'";
216-
PGresult *tresult = PQexec(pd, (const char *)(sql.utf8()));
217-
QString attnum = PQgetvalue(tresult, 0, 0);
218-
PQclear(tresult);
219-
220-
sql = "SELECT description FROM pg_description WHERE "
221-
"objoid = " + tableoid + " AND objsubid = " + attnum;
222-
tresult = PQexec(pd, (const char*)(sql.utf8()));
223-
if (PQntuples(tresult) > 0)
224-
fieldComment = PQgetvalue(tresult, 0, 0);
225-
PQclear(tresult);
226-
227-
QgsDebugMsg("Field: " + attnum + " maps to " + QString::number(i) + " " + fieldName + ", "
228-
+ fieldTypeName + " (" + QString::number(fldtyp) + "), " + fieldSize + ", " + QString::number(fieldModifier));
229-
230-
attributeFieldsIdMap[attnum.toInt()] = i;
249+
QVariant::Type fieldType;
250+
if (fieldTypeName.find("int") != -1 || fieldTypeName.find("serial") != -1)
251+
fieldType = QVariant::Int;
252+
else if (fieldTypeName == "real" || fieldTypeName == "double precision" || \
253+
fieldTypeName.find("float") != -1)
254+
fieldType = QVariant::Double;
255+
else
256+
fieldType = QVariant::String;
257+
attributeFields.insert(i, QgsField(fieldName, fieldType, fieldTypeName, fieldSize.toInt(), fieldModifier, fieldComment));
258+
}
259+
}
260+
PQclear(result);
231261

232-
if(fieldName!=geometryColumn)
233-
{
234-
QVariant::Type fieldType;
235-
if (fieldTypeName.find("int") != -1 || fieldTypeName.find("serial") != -1)
236-
fieldType = QVariant::Int;
237-
else if (fieldTypeName == "real" || fieldTypeName == "double precision" || \
238-
fieldTypeName.find("float") != -1)
239-
fieldType = QVariant::Double;
240-
else
241-
fieldType = QVariant::String;
242-
attributeFields.insert(i, QgsField(fieldName, fieldType, fieldTypeName, fieldSize.toInt(), fieldModifier, fieldComment));
243-
}
244-
}
245-
PQclear(result);
262+
// set the primary key
263+
getPrimaryKey();
246264

247-
// set the primary key
248-
getPrimaryKey();
249-
250-
// Set the postgresql message level so that we don't get the
251-
// 'there is no transaction in progress' warning.
265+
// Set the postgresql message level so that we don't get the
266+
// 'there is no transaction in progress' warning.
252267
#ifndef QGISDEBUG
253-
PQexec(connection, "set client_min_messages to error");
268+
PQexec(connection, "set client_min_messages to error");
254269
#endif
255270

256-
// Kick off the long running threads
271+
// Kick off the long running threads
257272

258273
#ifdef POSTGRESQL_THREADS
259-
QgsDebugMsg("About to touch mExtentThread");
260-
mExtentThread.setConnInfo( mUri.connInfo );
261-
mExtentThread.setTableName( mTableName );
262-
mExtentThread.setSqlWhereClause( sqlWhereClause );
263-
mExtentThread.setGeometryColumn( geometryColumn );
264-
mExtentThread.setCallback( this );
265-
QgsDebugMsg("About to start mExtentThread");
266-
mExtentThread.start();
267-
QgsDebugMsg("Main thread just dispatched mExtentThread");
268-
269-
QgsDebugMsg("About to touch mCountThread");
270-
mCountThread.setConnInfo( mUri.connInfo );
271-
mCountThread.setTableName( mTableName );
272-
mCountThread.setSqlWhereClause( sqlWhereClause );
273-
mCountThread.setGeometryColumn( geometryColumn );
274-
mCountThread.setCallback( this );
275-
QgsDebugMsg("About to start mCountThread");
276-
mCountThread.start();
277-
QgsDebugMsg("Main thread just dispatched mCountThread");
274+
QgsDebugMsg("About to touch mExtentThread");
275+
mExtentThread.setConnInfo( mUri.connInfo );
276+
mExtentThread.setTableName( mTableName );
277+
mExtentThread.setSqlWhereClause( sqlWhereClause );
278+
mExtentThread.setGeometryColumn( geometryColumn );
279+
mExtentThread.setCallback( this );
280+
QgsDebugMsg("About to start mExtentThread");
281+
mExtentThread.start();
282+
QgsDebugMsg("Main thread just dispatched mExtentThread");
283+
284+
QgsDebugMsg("About to touch mCountThread");
285+
mCountThread.setConnInfo( mUri.connInfo );
286+
mCountThread.setTableName( mTableName );
287+
mCountThread.setSqlWhereClause( sqlWhereClause );
288+
mCountThread.setGeometryColumn( geometryColumn );
289+
mCountThread.setCallback( this );
290+
QgsDebugMsg("About to start mCountThread");
291+
mCountThread.start();
292+
QgsDebugMsg("Main thread just dispatched mCountThread");
278293
#endif
279-
}
280-
else
281-
{
282-
// the table is not a geometry table
283-
numberFeatures = 0;
284-
valid = false;
285-
286-
QgsDebugMsg("Invalid Postgres layer");
287-
}
288-
289-
ready = false; // not ready to read yet cuz the cursor hasn't been created
290294

291-
} else {
292-
valid = false;
293-
//--std::cout << "Connection to database failed\n";
294-
}
295+
ready = false; // not ready to read yet cuz the cursor hasn't been created
295296

296297
//fill type names into sets
297298
mSupportedNativeTypes.insert("double precision");

0 commit comments

Comments
 (0)