@@ -70,6 +70,12 @@ static bool tableExists( QgsPostgresConn &conn, const QString &name )
70
70
return res.PQgetvalue ( 0 , 0 ).startsWith ( ' t' );
71
71
}
72
72
73
+ static bool columnExists ( QgsPostgresConn &conn, const QString &table, const QString &column )
74
+ {
75
+ QgsPostgresResult res ( conn.PQexec ( " SELECT COUNT(*) FROM information_schema.columns WHERE table_name=" + QgsPostgresConn::quotedValue ( table ) + " and column_name=" + QgsPostgresConn::quotedValue ( column ) ) );
76
+ return res.PQgetvalue ( 0 , 0 ).toInt () > 0 ;
77
+ }
78
+
73
79
QgsPostgresPrimaryKeyType
74
80
QgsPostgresProvider::pkType ( const QgsField &f ) const
75
81
{
@@ -4877,26 +4883,43 @@ bool QgsPostgresProviderMetadata::saveStyle( const QString &uri, const QString &
4877
4883
return false ;
4878
4884
}
4879
4885
4880
- QgsPostgresResult res ( conn->PQexec ( " CREATE TABLE IF NOT EXISTS layer_styles("
4881
- " id SERIAL PRIMARY KEY"
4882
- " ,f_table_catalog varchar"
4883
- " ,f_table_schema varchar"
4884
- " ,f_table_name varchar"
4885
- " ,f_geometry_column varchar"
4886
- " ,styleName text"
4887
- " ,styleQML xml"
4888
- " ,styleSLD xml"
4889
- " ,useAsDefault boolean"
4890
- " ,description text"
4891
- " ,owner varchar(63) DEFAULT CURRENT_USER"
4892
- " ,ui xml"
4893
- " ,update_time timestamp DEFAULT CURRENT_TIMESTAMP"
4894
- " )" ) );
4895
- if ( res.PQresultStatus () != PGRES_COMMAND_OK )
4896
- {
4897
- errCause = QObject::tr ( " Unable to save layer style. It's not possible to create the destination table on the database. Maybe this is due to table permissions (user=%1). Please contact your database admin" ).arg ( dsUri.username () );
4898
- conn->unref ();
4899
- return false ;
4886
+ if ( !tableExists ( *conn, QStringLiteral ( " layer_styles" ) ) )
4887
+ {
4888
+ QgsPostgresResult res ( conn->PQexec ( " CREATE TABLE layer_styles("
4889
+ " id SERIAL PRIMARY KEY"
4890
+ " ,f_table_catalog varchar"
4891
+ " ,f_table_schema varchar"
4892
+ " ,f_table_name varchar"
4893
+ " ,f_geometry_column varchar"
4894
+ " ,styleName text"
4895
+ " ,styleQML xml"
4896
+ " ,styleSLD xml"
4897
+ " ,useAsDefault boolean"
4898
+ " ,description text"
4899
+ " ,owner varchar(63) DEFAULT CURRENT_USER"
4900
+ " ,ui xml"
4901
+ " ,update_time timestamp DEFAULT CURRENT_TIMESTAMP"
4902
+ " ,type varchar"
4903
+ " )" ) );
4904
+ if ( res.PQresultStatus () != PGRES_COMMAND_OK )
4905
+ {
4906
+ errCause = QObject::tr ( " Unable to save layer style. It's not possible to create the destination table on the database. Maybe this is due to table permissions (user=%1). Please contact your database admin" ).arg ( dsUri.username () );
4907
+ conn->unref ();
4908
+ return false ;
4909
+ }
4910
+ }
4911
+ else
4912
+ {
4913
+ if ( !columnExists ( *conn, QStringLiteral ( " layer_styles" ), QStringLiteral ( " type" ) ) )
4914
+ {
4915
+ QgsPostgresResult res ( conn->PQexec ( " ALTER TABLE layer_styles ADD COLUMN type varchar NULL" ) );
4916
+ if ( res.PQresultStatus () != PGRES_COMMAND_OK )
4917
+ {
4918
+ errCause = QObject::tr ( " Unable to add column type to layer_styles table. Maybe this is due to table permissions (user=%1). Please contact your database admin" ).arg ( dsUri.username () );
4919
+ conn->unref ();
4920
+ return false ;
4921
+ }
4922
+ }
4900
4923
}
4901
4924
4902
4925
if ( dsUri.database ().isEmpty () ) // typically when a service file is used
@@ -4912,15 +4935,17 @@ bool QgsPostgresProviderMetadata::saveStyle( const QString &uri, const QString &
4912
4935
uiFileValue = QStringLiteral ( " ,XMLPARSE(DOCUMENT %1)" ).arg ( QgsPostgresConn::quotedValue ( uiFileContent ) );
4913
4936
}
4914
4937
4938
+ const QString wkbTypeString = QgsPostgresConn::quotedValue ( QgsWkbTypes::geometryDisplayString ( QgsWkbTypes::geometryType ( dsUri.wkbType () ) ) );
4939
+
4915
4940
// Note: in the construction of the INSERT and UPDATE strings the qmlStyle and sldStyle values
4916
4941
// can contain user entered strings, which may themselves include %## values that would be
4917
4942
// replaced by the QString.arg function. To ensure that the final SQL string is not corrupt these
4918
4943
// two values are both replaced in the final .arg call of the string construction.
4919
4944
4920
4945
QString sql = QString ( " INSERT INTO layer_styles("
4921
- " f_table_catalog,f_table_schema,f_table_name,f_geometry_column,styleName,styleQML,styleSLD,useAsDefault,description,owner%11 "
4946
+ " f_table_catalog,f_table_schema,f_table_name,f_geometry_column,styleName,styleQML,styleSLD,useAsDefault,description,owner,type%12 "
4922
4947
" ) VALUES ("
4923
- " %1,%2,%3,%4,%5,XMLPARSE(DOCUMENT %16),XMLPARSE(DOCUMENT %17),%8,%9,%10%12 "
4948
+ " %1,%2,%3,%4,%5,XMLPARSE(DOCUMENT %16),XMLPARSE(DOCUMENT %17),%8,%9,%10,%11%13 "
4924
4949
" )" )
4925
4950
.arg ( QgsPostgresConn::quotedValue ( dsUri.database () ) )
4926
4951
.arg ( QgsPostgresConn::quotedValue ( dsUri.schema () ) )
@@ -4932,6 +4957,7 @@ bool QgsPostgresProviderMetadata::saveStyle( const QString &uri, const QString &
4932
4957
.arg ( " CURRENT_USER" )
4933
4958
.arg ( uiFileColumn )
4934
4959
.arg ( uiFileValue )
4960
+ .arg ( wkbTypeString )
4935
4961
// Must be the final .arg replacement - see above
4936
4962
.arg ( QgsPostgresConn::quotedValue ( qmlStyle ),
4937
4963
QgsPostgresConn::quotedValue ( sldStyle ) );
@@ -4942,14 +4968,16 @@ bool QgsPostgresProviderMetadata::saveStyle( const QString &uri, const QString &
4942
4968
" AND f_table_schema=%2"
4943
4969
" AND f_table_name=%3"
4944
4970
" AND f_geometry_column=%4"
4945
- " AND styleName=%5" )
4971
+ " AND type=%5"
4972
+ " AND styleName=%6" )
4946
4973
.arg ( QgsPostgresConn::quotedValue ( dsUri.database () ) )
4947
4974
.arg ( QgsPostgresConn::quotedValue ( dsUri.schema () ) )
4948
4975
.arg ( QgsPostgresConn::quotedValue ( dsUri.table () ) )
4949
4976
.arg ( QgsPostgresConn::quotedValue ( dsUri.geometryColumn () ) )
4977
+ .arg ( wkbTypeString )
4950
4978
.arg ( QgsPostgresConn::quotedValue ( styleName.isEmpty () ? dsUri.table () : styleName ) );
4951
4979
4952
- res = conn->PQexec ( checkQuery );
4980
+ QgsPostgresResult res ( conn->PQexec ( checkQuery ) );
4953
4981
if ( res.PQntuples () > 0 )
4954
4982
{
4955
4983
if ( QMessageBox::question ( nullptr , QObject::tr ( " Save style in database" ),
@@ -4972,8 +5000,10 @@ bool QgsPostgresProviderMetadata::saveStyle( const QString &uri, const QString &
4972
5000
" AND f_table_schema=%7"
4973
5001
" AND f_table_name=%8"
4974
5002
" AND f_geometry_column=%9"
4975
- " AND styleName=%10" )
5003
+ " AND styleName=%10"
5004
+ " AND type=%2" )
4976
5005
.arg ( useAsDefault ? " true" : " false" )
5006
+ .arg ( wkbTypeString )
4977
5007
.arg ( QgsPostgresConn::quotedValue ( styleDescription.isEmpty () ? QDateTime::currentDateTime ().toString () : styleDescription ) )
4978
5008
.arg ( " CURRENT_USER" )
4979
5009
.arg ( QgsPostgresConn::quotedValue ( dsUri.database () ) )
@@ -4993,11 +5023,14 @@ bool QgsPostgresProviderMetadata::saveStyle( const QString &uri, const QString &
4993
5023
" WHERE f_table_catalog=%1"
4994
5024
" AND f_table_schema=%2"
4995
5025
" AND f_table_name=%3"
4996
- " AND f_geometry_column=%4" )
5026
+ " AND f_geometry_column=%4"
5027
+ " AND type=%5" )
4997
5028
.arg ( QgsPostgresConn::quotedValue ( dsUri.database () ) )
4998
5029
.arg ( QgsPostgresConn::quotedValue ( dsUri.schema () ) )
4999
5030
.arg ( QgsPostgresConn::quotedValue ( dsUri.table () ) )
5000
- .arg ( QgsPostgresConn::quotedValue ( dsUri.geometryColumn () ) );
5031
+ .arg ( QgsPostgresConn::quotedValue ( dsUri.geometryColumn () ) )
5032
+ .arg ( wkbTypeString );
5033
+
5001
5034
sql = QStringLiteral ( " BEGIN; %1; %2; COMMIT;" ).arg ( removeDefaultSql, sql );
5002
5035
}
5003
5036
@@ -5045,18 +5078,22 @@ QString QgsPostgresProviderMetadata::loadStyle( const QString &uri, QString &err
5045
5078
geomColumnExpr = QStringLiteral ( " =" ) + QgsPostgresConn::quotedValue ( dsUri.geometryColumn () );
5046
5079
}
5047
5080
5081
+ QString wkbTypeString = QgsPostgresConn::quotedValue ( QgsWkbTypes::geometryDisplayString ( QgsWkbTypes::geometryType ( dsUri.wkbType () ) ) );
5082
+
5048
5083
QString selectQmlQuery = QString ( " SELECT styleQML"
5049
5084
" FROM layer_styles"
5050
5085
" WHERE f_table_catalog=%1"
5051
5086
" AND f_table_schema=%2"
5052
5087
" AND f_table_name=%3"
5053
5088
" AND f_geometry_column %4"
5089
+ " AND type=%5"
5054
5090
" ORDER BY CASE WHEN useAsDefault THEN 1 ELSE 2 END"
5055
5091
" ,update_time DESC LIMIT 1" )
5056
5092
.arg ( QgsPostgresConn::quotedValue ( dsUri.database () ) )
5057
5093
.arg ( QgsPostgresConn::quotedValue ( dsUri.schema () ) )
5058
5094
.arg ( QgsPostgresConn::quotedValue ( dsUri.table () ) )
5059
- .arg ( geomColumnExpr );
5095
+ .arg ( geomColumnExpr )
5096
+ .arg ( wkbTypeString );
5060
5097
5061
5098
QgsPostgresResult result ( conn->PQexec ( selectQmlQuery ) );
5062
5099
@@ -5083,17 +5120,21 @@ int QgsPostgresProviderMetadata::listStyles( const QString &uri, QStringList &id
5083
5120
dsUri.setDatabase ( conn->currentDatabase () );
5084
5121
}
5085
5122
5123
+ QString wkbTypeString = QgsPostgresConn::quotedValue ( QgsWkbTypes::geometryDisplayString ( QgsWkbTypes::geometryType ( dsUri.wkbType () ) ) );
5124
+
5086
5125
QString selectRelatedQuery = QString ( " SELECT id,styleName,description"
5087
5126
" FROM layer_styles"
5088
5127
" WHERE f_table_catalog=%1"
5089
5128
" AND f_table_schema=%2"
5090
5129
" AND f_table_name=%3"
5091
5130
" AND f_geometry_column=%4"
5131
+ " AND type=%5"
5092
5132
" ORDER BY useasdefault DESC, update_time DESC" )
5093
5133
.arg ( QgsPostgresConn::quotedValue ( dsUri.database () ) )
5094
5134
.arg ( QgsPostgresConn::quotedValue ( dsUri.schema () ) )
5095
5135
.arg ( QgsPostgresConn::quotedValue ( dsUri.table () ) )
5096
- .arg ( QgsPostgresConn::quotedValue ( dsUri.geometryColumn () ) );
5136
+ .arg ( QgsPostgresConn::quotedValue ( dsUri.geometryColumn () ) )
5137
+ .arg ( wkbTypeString );
5097
5138
5098
5139
QgsPostgresResult result ( conn->PQexec ( selectRelatedQuery ) );
5099
5140
if ( result.PQresultStatus () != PGRES_TUPLES_OK )
@@ -5114,12 +5155,13 @@ int QgsPostgresProviderMetadata::listStyles( const QString &uri, QStringList &id
5114
5155
5115
5156
QString selectOthersQuery = QString ( " SELECT id,styleName,description"
5116
5157
" FROM layer_styles"
5117
- " WHERE NOT (f_table_catalog=%1 AND f_table_schema=%2 AND f_table_name=%3 AND f_geometry_column=%4)"
5158
+ " WHERE NOT (f_table_catalog=%1 AND f_table_schema=%2 AND f_table_name=%3 AND f_geometry_column=%4 AND type=%5 )"
5118
5159
" ORDER BY update_time DESC" )
5119
5160
.arg ( QgsPostgresConn::quotedValue ( dsUri.database () ) )
5120
5161
.arg ( QgsPostgresConn::quotedValue ( dsUri.schema () ) )
5121
5162
.arg ( QgsPostgresConn::quotedValue ( dsUri.table () ) )
5122
- .arg ( QgsPostgresConn::quotedValue ( dsUri.geometryColumn () ) );
5163
+ .arg ( QgsPostgresConn::quotedValue ( dsUri.geometryColumn () ) )
5164
+ .arg ( wkbTypeString );
5123
5165
5124
5166
result = conn->PQexec ( selectOthersQuery );
5125
5167
if ( result.PQresultStatus () != PGRES_TUPLES_OK )
0 commit comments