24
24
#include < netinet/in.h>
25
25
#endif
26
26
27
- #include < cassert>
28
-
29
27
#include < qgis.h>
30
28
#include < qgsapplication.h>
31
29
#include < qgsfeature.h>
@@ -191,12 +189,12 @@ QgsPostgresProvider::QgsPostgresProvider( QString const & uri )
191
189
calculateExtents ();
192
190
getFeatureCount ();
193
191
194
- // load the field list
195
- loadFields ();
196
-
197
192
// set the primary key
198
193
getPrimaryKey ();
199
194
195
+ // load the field list
196
+ loadFields ();
197
+
200
198
// Set the postgresql message level so that we don't get the
201
199
// 'there is no transaction in progress' warning.
202
200
#ifndef QGISDEBUG
@@ -870,6 +868,9 @@ void QgsPostgresProvider::loadFields()
870
868
for ( int i = 0 ; i < PQnfields ( result ); i++ )
871
869
{
872
870
QString fieldName = QString::fromUtf8 ( PQfname ( result, i ) );
871
+ if ( fieldName == geometryColumn )
872
+ continue ;
873
+
873
874
int fldtyp = PQftype ( result, i );
874
875
QString typOid = QString ().setNum ( fldtyp );
875
876
int fieldModifier = PQfmod ( result, i );
@@ -899,79 +900,76 @@ void QgsPostgresProvider::loadFields()
899
900
if ( PQntuples ( tresult ) > 0 )
900
901
fieldComment = QString::fromUtf8 ( PQgetvalue ( tresult, 0 , 0 ) );
901
902
902
- if ( fieldName != geometryColumn )
903
- {
904
- QVariant::Type fieldType;
905
-
906
- if ( fieldTType == " b" )
907
- {
908
- bool isArray = fieldTypeName.startsWith ( " _" );
903
+ QVariant::Type fieldType;
909
904
910
- if ( isArray )
911
- fieldTypeName = fieldTypeName.mid ( 1 );
905
+ if ( fieldTType == " b" )
906
+ {
907
+ bool isArray = fieldTypeName.startsWith ( " _" );
912
908
913
- if ( fieldTypeName == " int8" )
914
- {
915
- fieldType = QVariant::LongLong;
916
- fieldSize = -1 ;
917
- }
918
- else if ( fieldTypeName.startsWith ( " int" ) ||
919
- fieldTypeName == " serial" )
920
- {
921
- fieldType = QVariant::Int;
922
- fieldSize = -1 ;
923
- }
924
- else if ( fieldTypeName == " real" ||
925
- fieldTypeName == " double precision" ||
926
- fieldTypeName.startsWith ( " float" ) ||
927
- fieldTypeName == " numeric" )
928
- {
929
- fieldType = QVariant::Double;
930
- fieldSize = -1 ;
931
- }
932
- else if ( fieldTypeName == " text" ||
933
- fieldTypeName == " bpchar" ||
934
- fieldTypeName == " varchar" ||
935
- fieldTypeName == " bool" ||
936
- fieldTypeName == " geometry" ||
937
- fieldTypeName == " money" ||
938
- fieldTypeName.startsWith ( " time" ) ||
939
- fieldTypeName.startsWith ( " date" ) )
940
- {
941
- fieldType = QVariant::String;
942
- fieldSize = -1 ;
943
- }
944
- else if ( fieldTypeName == " char" )
945
- {
946
- fieldType = QVariant::String;
947
- }
948
- else
949
- {
950
- QgsDebugMsg ( " Field " + fieldName + " ignored, because of unsupported type " + fieldTypeName );
951
- continue ;
952
- }
909
+ if ( isArray )
910
+ fieldTypeName = fieldTypeName.mid ( 1 );
953
911
954
- if ( isArray )
955
- {
956
- fieldTypeName = " _" + fieldTypeName;
957
- fieldType = QVariant::String;
958
- fieldSize = -1 ;
959
- }
912
+ if ( fieldTypeName == " int8" )
913
+ {
914
+ fieldType = QVariant::LongLong;
915
+ fieldSize = -1 ;
916
+ }
917
+ else if ( fieldTypeName.startsWith ( " int" ) ||
918
+ fieldTypeName == " serial" )
919
+ {
920
+ fieldType = QVariant::Int;
921
+ fieldSize = -1 ;
960
922
}
961
- else if ( fieldTType == " e" )
923
+ else if ( fieldTypeName == " real" ||
924
+ fieldTypeName == " double precision" ||
925
+ fieldTypeName.startsWith ( " float" ) ||
926
+ fieldTypeName == " numeric" )
927
+ {
928
+ fieldType = QVariant::Double;
929
+ fieldSize = -1 ;
930
+ }
931
+ else if ( fieldTypeName == " text" ||
932
+ fieldTypeName == " bpchar" ||
933
+ fieldTypeName == " varchar" ||
934
+ fieldTypeName == " bool" ||
935
+ fieldTypeName == " geometry" ||
936
+ fieldTypeName == " money" ||
937
+ fieldTypeName.startsWith ( " time" ) ||
938
+ fieldTypeName.startsWith ( " date" ) )
962
939
{
963
- // enum
964
940
fieldType = QVariant::String;
965
941
fieldSize = -1 ;
966
942
}
943
+ else if ( fieldTypeName == " char" )
944
+ {
945
+ fieldType = QVariant::String;
946
+ }
967
947
else
968
948
{
969
- QgsDebugMsg ( " Field " + fieldName + " ignored, because of unsupported type type " + fieldTType );
949
+ QgsDebugMsg ( " Field " + fieldName + " ignored, because of unsupported type " + fieldTypeName );
970
950
continue ;
971
951
}
972
952
973
- attributeFields.insert ( i, QgsField ( fieldName, fieldType, fieldTypeName, fieldSize, fieldModifier, fieldComment ) );
953
+ if ( isArray )
954
+ {
955
+ fieldTypeName = " _" + fieldTypeName;
956
+ fieldType = QVariant::String;
957
+ fieldSize = -1 ;
958
+ }
974
959
}
960
+ else if ( fieldTType == " e" )
961
+ {
962
+ // enum
963
+ fieldType = QVariant::String;
964
+ fieldSize = -1 ;
965
+ }
966
+ else
967
+ {
968
+ QgsDebugMsg ( " Field " + fieldName + " ignored, because of unsupported type type " + fieldTType );
969
+ continue ;
970
+ }
971
+
972
+ attributeFields.insert ( i, QgsField ( fieldName, fieldType, fieldTypeName, fieldSize, fieldModifier, fieldComment ) );
975
973
}
976
974
}
977
975
@@ -1064,6 +1062,17 @@ QString QgsPostgresProvider::getPrimaryKey()
1064
1062
" primary key), has a PostgreSQL oid column or has a ctid\n "
1065
1063
" column with a 16bit block number.\n " ) );
1066
1064
}
1065
+ else
1066
+ {
1067
+ primaryKeyDefault = defaultValue ( primaryKey ).toString ();
1068
+ if ( primaryKeyDefault.isNull () )
1069
+ {
1070
+ primaryKeyDefault = QString ( " max(%1)+1 from %2.%3" )
1071
+ .arg ( quotedIdentifier ( primaryKey ) )
1072
+ .arg ( quotedIdentifier ( mSchemaName ) )
1073
+ .arg ( quotedIdentifier ( mTableName ) );
1074
+ }
1075
+ }
1067
1076
}
1068
1077
else if ( type == " v" ) // the relation is a view
1069
1078
{
@@ -1091,18 +1100,33 @@ QString QgsPostgresProvider::getPrimaryKey()
1091
1100
}
1092
1101
}
1093
1102
1103
+ // Have a poke around the view to see if any of the columns
1104
+ // could be used as the primary key.
1105
+ tableCols cols;
1106
+
1107
+ // Given a schema.view, populate the cols variable with the
1108
+ // schema.table.column's that underly the view columns.
1109
+ findColumns ( cols );
1110
+
1094
1111
if ( primaryKey.isEmpty () )
1095
1112
{
1096
- // Have a poke around the view to see if any of the columns
1097
- // could be used as the primary key.
1098
- tableCols cols;
1099
- // Given a schema.view, populate the cols variable with the
1100
- // schema.table.column's that underly the view columns.
1101
- findColumns ( cols );
1102
1113
// From the view columns, choose one for which the underlying
1103
1114
// column is suitable for use as a key into the view.
1104
1115
primaryKey = chooseViewColumn ( cols );
1105
1116
}
1117
+
1118
+ tableCols::const_iterator it = cols.find ( primaryKey );
1119
+ if ( it != cols.end () )
1120
+ {
1121
+ primaryKeyDefault = defaultValue ( it->second .column , it->second .relation , it->second .schema ).toString ();
1122
+ if ( primaryKeyDefault.isNull () )
1123
+ {
1124
+ primaryKeyDefault = QString ( " max(%1)+1 from %2.%3" )
1125
+ .arg ( quotedIdentifier ( it->second .column ) )
1126
+ .arg ( quotedIdentifier ( it->second .schema ) )
1127
+ .arg ( quotedIdentifier ( it->second .relation ) );
1128
+ }
1129
+ }
1106
1130
}
1107
1131
else
1108
1132
QgsDebugMsg ( " Unexpected relation type of '" + type + " '." );
@@ -1201,9 +1225,20 @@ QString QgsPostgresProvider::getPrimaryKey()
1201
1225
valid = false ;
1202
1226
showMessageBox ( tr ( " Unable to find a key column" ), log );
1203
1227
}
1228
+ else
1229
+ {
1230
+ primaryKeyDefault = defaultValue ( primaryKey ).toString ();
1231
+ if ( primaryKeyDefault.isNull () )
1232
+ {
1233
+ primaryKeyDefault = QString ( " max(%1)+1 from %2.%3" )
1234
+ .arg ( quotedIdentifier ( primaryKey ) )
1235
+ .arg ( quotedIdentifier ( mSchemaName ) )
1236
+ .arg ( quotedIdentifier ( mTableName ) );
1237
+ }
1238
+ }
1204
1239
}
1205
1240
1206
- if ( primaryKey.length () > 0 )
1241
+ if ( ! primaryKey.isNull () )
1207
1242
{
1208
1243
QgsDebugMsg ( " Qgis row key is " + primaryKey );
1209
1244
}
@@ -1893,28 +1928,18 @@ QVariant QgsPostgresProvider::maximumValue( int index )
1893
1928
}
1894
1929
1895
1930
1896
- int QgsPostgresProvider::maxPrimaryKeyValue ()
1897
- {
1898
- QString sql;
1899
-
1900
- sql = QString ( " select max(%1) from %2" )
1901
- .arg ( quotedIdentifier ( primaryKey ) )
1902
- .arg ( mSchemaTableName );
1903
-
1904
- Result rmax = connectionRO->PQexec ( sql );
1905
- QString maxValue = QString::fromUtf8 ( PQgetvalue ( rmax, 0 , 0 ) );
1906
-
1907
- return maxValue.toInt ();
1908
- }
1909
-
1910
-
1911
1931
bool QgsPostgresProvider::isValid ()
1912
1932
{
1913
1933
return valid;
1914
1934
}
1915
1935
1916
- QVariant QgsPostgresProvider::defaultValue ( QString fieldName )
1936
+ QVariant QgsPostgresProvider::defaultValue ( QString fieldName, QString tableName, QString schemaName )
1917
1937
{
1938
+ if ( schemaName.isNull () )
1939
+ schemaName = mSchemaName ;
1940
+ if ( tableName.isNull () )
1941
+ tableName = mTableName ;
1942
+
1918
1943
// Get the default column value from the Postgres information
1919
1944
// schema. If there is no default we return an empty string.
1920
1945
@@ -1924,8 +1949,8 @@ QVariant QgsPostgresProvider::defaultValue( QString fieldName )
1924
1949
QString sql ( " SELECT column_default FROM"
1925
1950
" information_schema.columns WHERE"
1926
1951
" column_default IS NOT NULL"
1927
- " AND table_schema = " + quotedValue ( mSchemaName ) +
1928
- " AND table_name = " + quotedValue ( mTableName ) +
1952
+ " AND table_schema = " + quotedValue ( schemaName ) +
1953
+ " AND table_name = " + quotedValue ( tableName ) +
1929
1954
" AND column_name = " + quotedValue ( fieldName ) );
1930
1955
1931
1956
QVariant defaultValue ( QString::null );
@@ -1935,8 +1960,6 @@ QVariant QgsPostgresProvider::defaultValue( QString fieldName )
1935
1960
if ( PQntuples ( result ) == 1 && !PQgetisnull ( result, 0 , 0 ) )
1936
1961
defaultValue = QString::fromUtf8 ( PQgetvalue ( result, 0 , 0 ) );
1937
1962
1938
- // QgsDebugMsg( QString("defaultValue for %1 is NULL: %2").arg(fieldId).arg( defaultValue.isNull() ) );
1939
-
1940
1963
return defaultValue;
1941
1964
}
1942
1965
@@ -2084,7 +2107,6 @@ bool QgsPostgresProvider::addFeatures( QgsFeatureList &flist )
2084
2107
2085
2108
QStringList defaultValues;
2086
2109
QList<int > fieldId;
2087
- int primaryKeyId = -1 ;
2088
2110
2089
2111
// look for unique attribute values to place in statement instead of passing as parameter
2090
2112
// e.g. for defaults
@@ -2098,15 +2120,9 @@ bool QgsPostgresProvider::addFeatures( QgsFeatureList &flist )
2098
2120
2099
2121
QgsDebugMsg ( " Checking field against: " + fieldname );
2100
2122
2101
- if ( fieldname.isEmpty () || fieldname == geometryColumn )
2123
+ if ( fieldname.isEmpty () || fieldname == geometryColumn || fieldname == primaryKey )
2102
2124
continue ;
2103
2125
2104
- if ( fieldname == primaryKey )
2105
- {
2106
- primaryKeyId = it.key ();
2107
- continue ;
2108
- }
2109
-
2110
2126
int i;
2111
2127
for ( i = 1 ; i < flist.size (); i++ )
2112
2128
{
@@ -2170,10 +2186,6 @@ bool QgsPostgresProvider::addFeatures( QgsFeatureList &flist )
2170
2186
throw PGException ( stmt );
2171
2187
PQclear ( stmt );
2172
2188
2173
- QString keyDefault = defaultValue ( primaryKey ).toString ();
2174
- int primaryKeyHighWater = -1 ;
2175
- if ( keyDefault.isNull () )
2176
- primaryKeyHighWater = maxPrimaryKeyValue ();
2177
2189
QList<int > newIds;
2178
2190
2179
2191
for ( QgsFeatureList::iterator features = flist.begin (); features != flist.end (); features++ )
@@ -2188,19 +2200,9 @@ bool QgsPostgresProvider::addFeatures( QgsFeatureList &flist )
2188
2200
2189
2201
if ( primaryKeyType != " tid" )
2190
2202
{
2191
- QByteArray key = paramValue ( primaryKeyId >= 0 ? attributevec[ primaryKeyId ].toString () : QString::null, keyDefault );
2192
-
2193
- if ( key.isNull () )
2194
- {
2195
- ++primaryKeyHighWater;
2196
- params << QString::number ( primaryKeyHighWater );
2197
- newIds << primaryKeyHighWater;
2198
- }
2199
- else
2200
- {
2201
- params << key;
2202
- newIds << key.toInt ();
2203
- }
2203
+ int id = paramValue ( primaryKeyDefault, primaryKeyDefault ).toInt ();
2204
+ params << QString::number ( id );
2205
+ newIds << id;
2204
2206
}
2205
2207
2206
2208
for ( int i = 0 ; i < fieldId.size (); i++ )
@@ -3111,8 +3113,7 @@ void QgsPostgresProvider::showMessageBox( const QString& title, const QString& t
3111
3113
message->showMessage ();
3112
3114
}
3113
3115
3114
- void QgsPostgresProvider::showMessageBox ( const QString& title,
3115
- const QStringList& text )
3116
+ void QgsPostgresProvider::showMessageBox ( const QString& title, const QStringList& text )
3116
3117
{
3117
3118
showMessageBox ( title, text.join ( " \n " ) );
3118
3119
}
0 commit comments