@@ -211,6 +211,7 @@ QgsPostgresConn::QgsPostgresConn( const QString &conninfo, bool readOnly, bool s
211
211
, mNextCursorId( 0 )
212
212
, mShared( shared )
213
213
, mTransaction( transaction )
214
+ , mLock( QMutex::Recursive )
214
215
{
215
216
QgsDebugMsg ( QStringLiteral ( " New PostgreSQL connection for " ) + conninfo );
216
217
@@ -1065,40 +1066,46 @@ PGresult *QgsPostgresConn::PQexec( const QString &query, bool logError ) const
1065
1066
}
1066
1067
1067
1068
QgsDebugMsgLevel ( QStringLiteral ( " Executing SQL: %1" ).arg ( query ), 3 );
1068
- PGresult *res = ::PQexec ( mConn , query.toUtf8 () );
1069
-
1070
- if ( res )
1069
+ PGresult *res = nullptr ;
1071
1070
{
1072
- int errorStatus = PQresultStatus ( res );
1073
- if ( errorStatus != PGRES_COMMAND_OK && errorStatus != PGRES_TUPLES_OK )
1071
+ QMutexLocker locker ( &mLock );
1072
+ res = ::PQexec ( mConn , query.toUtf8 () );
1073
+
1074
+ if ( res )
1074
1075
{
1075
- if ( logError )
1076
+ int errorStatus = PQresultStatus ( res );
1077
+ if ( errorStatus != PGRES_COMMAND_OK && errorStatus != PGRES_TUPLES_OK )
1076
1078
{
1077
- QgsMessageLog::logMessage ( tr ( " Erroneous query: %1 returned %2 [%3]" )
1078
- .arg ( query ).arg ( errorStatus ).arg ( PQresultErrorMessage ( res ) ),
1079
- tr ( " PostGIS" ) );
1080
- }
1081
- else
1082
- {
1083
- QgsDebugMsg ( QStringLiteral ( " Not logged erroneous query: %1 returned %2 [%3]" )
1084
- .arg ( query ).arg ( errorStatus ).arg ( PQresultErrorMessage ( res ) ) );
1079
+ if ( logError )
1080
+ {
1081
+ QgsMessageLog::logMessage ( tr ( " Erroneous query: %1 returned %2 [%3]" )
1082
+ .arg ( query ).arg ( errorStatus ).arg ( PQresultErrorMessage ( res ) ),
1083
+ tr ( " PostGIS" ) );
1084
+ }
1085
+ else
1086
+ {
1087
+ QgsDebugMsg ( QStringLiteral ( " Not logged erroneous query: %1 returned %2 [%3]" )
1088
+ .arg ( query ).arg ( errorStatus ).arg ( PQresultErrorMessage ( res ) ) );
1089
+ }
1085
1090
}
1086
1091
}
1087
- }
1088
- else if ( logError )
1089
- {
1090
- QgsMessageLog::logMessage ( tr ( " Query failed: %1 \n Error: no result buffer " ). arg ( query ), tr ( " PostGIS " ) );
1091
- }
1092
- else
1093
- {
1094
- QgsDebugMsg ( QStringLiteral ( " Not logged query failed: %1 \n Error: no result buffer " ). arg ( query ) );
1092
+ else if ( logError )
1093
+ {
1094
+ QgsMessageLog::logMessage ( tr ( " Query failed: %1 \n Error: no result buffer " ). arg ( query ), tr ( " PostGIS " ) );
1095
+ }
1096
+ else
1097
+ {
1098
+ QgsDebugMsg ( QStringLiteral ( " Not logged query failed: %1 \n Error: no result buffer " ). arg ( query ) );
1099
+ }
1095
1100
}
1096
1101
1097
1102
return res;
1098
1103
}
1099
1104
1100
1105
bool QgsPostgresConn::openCursor ( const QString &cursorName, const QString &sql )
1101
1106
{
1107
+ QMutexLocker locker ( &mLock ); // to protect access to mOpenCursors
1108
+
1102
1109
if ( mOpenCursors ++ == 0 && !mTransaction )
1103
1110
{
1104
1111
QgsDebugMsgLevel ( QStringLiteral ( " Starting read-only transaction: %1" ).arg ( mPostgresqlVersion ), 4 );
@@ -1114,6 +1121,8 @@ bool QgsPostgresConn::openCursor( const QString &cursorName, const QString &sql
1114
1121
1115
1122
bool QgsPostgresConn::closeCursor ( const QString &cursorName )
1116
1123
{
1124
+ QMutexLocker locker ( &mLock ); // to protect access to mOpenCursors
1125
+
1117
1126
if ( !PQexecNR ( QStringLiteral ( " CLOSE %1" ).arg ( cursorName ) ) )
1118
1127
return false ;
1119
1128
@@ -1128,11 +1137,14 @@ bool QgsPostgresConn::closeCursor( const QString &cursorName )
1128
1137
1129
1138
QString QgsPostgresConn::uniqueCursorName ()
1130
1139
{
1140
+ QMutexLocker locker ( &mLock ); // to protect access to mNextCursorId
1131
1141
return QStringLiteral ( " qgis_%1" ).arg ( ++mNextCursorId );
1132
1142
}
1133
1143
1134
1144
bool QgsPostgresConn::PQexecNR ( const QString &query, bool retry )
1135
1145
{
1146
+ QMutexLocker locker ( &mLock ); // to protect access to mOpenCursors
1147
+
1136
1148
QgsPostgresResult res ( PQexec ( query, false ) );
1137
1149
1138
1150
ExecStatusType errorStatus = res.PQresultStatus ();
@@ -1194,11 +1206,15 @@ PGresult *QgsPostgresConn::PQgetResult()
1194
1206
1195
1207
PGresult *QgsPostgresConn::PQprepare ( const QString &stmtName, const QString &query, int nParams, const Oid *paramTypes )
1196
1208
{
1209
+ QMutexLocker locker ( &mLock );
1210
+
1197
1211
return ::PQprepare ( mConn , stmtName.toUtf8 (), query.toUtf8 (), nParams, paramTypes );
1198
1212
}
1199
1213
1200
1214
PGresult *QgsPostgresConn::PQexecPrepared ( const QString &stmtName, const QStringList ¶ms )
1201
1215
{
1216
+ QMutexLocker locker ( &mLock );
1217
+
1202
1218
const char **param = new const char *[ params.size ()];
1203
1219
QList<QByteArray> qparam;
1204
1220
@@ -1222,19 +1238,25 @@ PGresult *QgsPostgresConn::PQexecPrepared( const QString &stmtName, const QStrin
1222
1238
1223
1239
void QgsPostgresConn::PQfinish ()
1224
1240
{
1241
+ QMutexLocker locker ( &mLock );
1242
+
1225
1243
Q_ASSERT ( mConn );
1226
1244
::PQfinish ( mConn );
1227
1245
mConn = nullptr ;
1228
1246
}
1229
1247
1230
1248
int QgsPostgresConn::PQstatus () const
1231
1249
{
1250
+ QMutexLocker locker ( &mLock );
1251
+
1232
1252
Q_ASSERT ( mConn );
1233
1253
return ::PQstatus ( mConn );
1234
1254
}
1235
1255
1236
1256
QString QgsPostgresConn::PQerrorMessage () const
1237
1257
{
1258
+ QMutexLocker locker ( &mLock );
1259
+
1238
1260
Q_ASSERT ( mConn );
1239
1261
return QString::fromUtf8 ( ::PQerrorMessage ( mConn ) );
1240
1262
}
0 commit comments