@@ -112,186 +112,187 @@ QgsPostgresProvider::QgsPostgresProvider(QString const & uri)
112
112
113
113
PGconn *pd = PQconnectdb ((const char *) mUri .connInfo );
114
114
// check the connection status
115
- if (PQstatus (pd) = = CONNECTION_OK)
115
+ if (PQstatus (pd) ! = CONNECTION_OK)
116
116
{
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;
119
124
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
+ }
132
137
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.\n The 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.\n The error message from the database was:\n " ) +
149
+ QString (PQresultErrorMessage (testAccess)) + " .\n " +
150
+ " SQL: " + sql);
150
151
PQclear (testAccess);
152
+ valid = false ;
153
+ PQfinish (connection);
154
+ return ;
155
+ }
156
+ PQclear (testAccess);
151
157
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" );
155
161
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.\n Please 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.\n Please install PostGIS with "
168
+ " GEOS support (http://geos.refractions.net)" ));
169
+ }
170
+ // --std::cout << "Connection to the database was successful\n";
165
171
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)
167
248
{
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);
231
261
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 ();
246
264
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.
252
267
#ifndef QGISDEBUG
253
- PQexec (connection, " set client_min_messages to error" );
268
+ PQexec (connection, " set client_min_messages to error" );
254
269
#endif
255
270
256
- // Kick off the long running threads
271
+ // Kick off the long running threads
257
272
258
273
#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" );
278
293
#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
290
294
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
295
296
296
297
// fill type names into sets
297
298
mSupportedNativeTypes .insert (" double precision" );
0 commit comments