Skip to content

Commit 4afd703

Browse files
author
jef
committed
better fix for #2137
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@12418 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent c110afe commit 4afd703

File tree

2 files changed

+124
-126
lines changed

2 files changed

+124
-126
lines changed

src/providers/postgres/qgspostgresprovider.cpp

Lines changed: 119 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424
#include <netinet/in.h>
2525
#endif
2626

27-
#include <cassert>
28-
2927
#include <qgis.h>
3028
#include <qgsapplication.h>
3129
#include <qgsfeature.h>
@@ -191,12 +189,12 @@ QgsPostgresProvider::QgsPostgresProvider( QString const & uri )
191189
calculateExtents();
192190
getFeatureCount();
193191

194-
// load the field list
195-
loadFields();
196-
197192
// set the primary key
198193
getPrimaryKey();
199194

195+
// load the field list
196+
loadFields();
197+
200198
// Set the postgresql message level so that we don't get the
201199
// 'there is no transaction in progress' warning.
202200
#ifndef QGISDEBUG
@@ -870,6 +868,9 @@ void QgsPostgresProvider::loadFields()
870868
for ( int i = 0; i < PQnfields( result ); i++ )
871869
{
872870
QString fieldName = QString::fromUtf8( PQfname( result, i ) );
871+
if ( fieldName == geometryColumn )
872+
continue;
873+
873874
int fldtyp = PQftype( result, i );
874875
QString typOid = QString().setNum( fldtyp );
875876
int fieldModifier = PQfmod( result, i );
@@ -899,79 +900,76 @@ void QgsPostgresProvider::loadFields()
899900
if ( PQntuples( tresult ) > 0 )
900901
fieldComment = QString::fromUtf8( PQgetvalue( tresult, 0, 0 ) );
901902

902-
if ( fieldName != geometryColumn )
903-
{
904-
QVariant::Type fieldType;
905-
906-
if ( fieldTType == "b" )
907-
{
908-
bool isArray = fieldTypeName.startsWith( "_" );
903+
QVariant::Type fieldType;
909904

910-
if ( isArray )
911-
fieldTypeName = fieldTypeName.mid( 1 );
905+
if ( fieldTType == "b" )
906+
{
907+
bool isArray = fieldTypeName.startsWith( "_" );
912908

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 );
953911

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;
960922
}
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" ) )
962939
{
963-
// enum
964940
fieldType = QVariant::String;
965941
fieldSize = -1;
966942
}
943+
else if ( fieldTypeName == "char" )
944+
{
945+
fieldType = QVariant::String;
946+
}
967947
else
968948
{
969-
QgsDebugMsg( "Field " + fieldName + " ignored, because of unsupported type type " + fieldTType );
949+
QgsDebugMsg( "Field " + fieldName + " ignored, because of unsupported type " + fieldTypeName );
970950
continue;
971951
}
972952

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+
}
974959
}
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 ) );
975973
}
976974
}
977975

@@ -1064,6 +1062,17 @@ QString QgsPostgresProvider::getPrimaryKey()
10641062
"primary key), has a PostgreSQL oid column or has a ctid\n"
10651063
"column with a 16bit block number.\n" ) );
10661064
}
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+
}
10671076
}
10681077
else if ( type == "v" ) // the relation is a view
10691078
{
@@ -1091,18 +1100,33 @@ QString QgsPostgresProvider::getPrimaryKey()
10911100
}
10921101
}
10931102

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+
10941111
if ( primaryKey.isEmpty() )
10951112
{
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 );
11021113
// From the view columns, choose one for which the underlying
11031114
// column is suitable for use as a key into the view.
11041115
primaryKey = chooseViewColumn( cols );
11051116
}
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+
}
11061130
}
11071131
else
11081132
QgsDebugMsg( "Unexpected relation type of '" + type + "'." );
@@ -1201,9 +1225,20 @@ QString QgsPostgresProvider::getPrimaryKey()
12011225
valid = false;
12021226
showMessageBox( tr( "Unable to find a key column" ), log );
12031227
}
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+
}
12041239
}
12051240

1206-
if ( primaryKey.length() > 0 )
1241+
if ( !primaryKey.isNull() )
12071242
{
12081243
QgsDebugMsg( "Qgis row key is " + primaryKey );
12091244
}
@@ -1893,28 +1928,18 @@ QVariant QgsPostgresProvider::maximumValue( int index )
18931928
}
18941929

18951930

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-
19111931
bool QgsPostgresProvider::isValid()
19121932
{
19131933
return valid;
19141934
}
19151935

1916-
QVariant QgsPostgresProvider::defaultValue( QString fieldName )
1936+
QVariant QgsPostgresProvider::defaultValue( QString fieldName, QString tableName, QString schemaName )
19171937
{
1938+
if ( schemaName.isNull() )
1939+
schemaName = mSchemaName;
1940+
if ( tableName.isNull() )
1941+
tableName = mTableName;
1942+
19181943
// Get the default column value from the Postgres information
19191944
// schema. If there is no default we return an empty string.
19201945

@@ -1924,8 +1949,8 @@ QVariant QgsPostgresProvider::defaultValue( QString fieldName )
19241949
QString sql( "SELECT column_default FROM"
19251950
" information_schema.columns WHERE"
19261951
" 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 ) +
19291954
" AND column_name = " + quotedValue( fieldName ) );
19301955

19311956
QVariant defaultValue( QString::null );
@@ -1935,8 +1960,6 @@ QVariant QgsPostgresProvider::defaultValue( QString fieldName )
19351960
if ( PQntuples( result ) == 1 && !PQgetisnull( result, 0, 0 ) )
19361961
defaultValue = QString::fromUtf8( PQgetvalue( result, 0, 0 ) );
19371962

1938-
// QgsDebugMsg( QString("defaultValue for %1 is NULL: %2").arg(fieldId).arg( defaultValue.isNull() ) );
1939-
19401963
return defaultValue;
19411964
}
19421965

@@ -2084,7 +2107,6 @@ bool QgsPostgresProvider::addFeatures( QgsFeatureList &flist )
20842107

20852108
QStringList defaultValues;
20862109
QList<int> fieldId;
2087-
int primaryKeyId = -1;
20882110

20892111
// look for unique attribute values to place in statement instead of passing as parameter
20902112
// e.g. for defaults
@@ -2098,15 +2120,9 @@ bool QgsPostgresProvider::addFeatures( QgsFeatureList &flist )
20982120

20992121
QgsDebugMsg( "Checking field against: " + fieldname );
21002122

2101-
if ( fieldname.isEmpty() || fieldname == geometryColumn )
2123+
if ( fieldname.isEmpty() || fieldname == geometryColumn || fieldname == primaryKey )
21022124
continue;
21032125

2104-
if ( fieldname == primaryKey )
2105-
{
2106-
primaryKeyId = it.key();
2107-
continue;
2108-
}
2109-
21102126
int i;
21112127
for ( i = 1; i < flist.size(); i++ )
21122128
{
@@ -2170,10 +2186,6 @@ bool QgsPostgresProvider::addFeatures( QgsFeatureList &flist )
21702186
throw PGException( stmt );
21712187
PQclear( stmt );
21722188

2173-
QString keyDefault = defaultValue( primaryKey ).toString();
2174-
int primaryKeyHighWater = -1;
2175-
if ( keyDefault.isNull() )
2176-
primaryKeyHighWater = maxPrimaryKeyValue();
21772189
QList<int> newIds;
21782190

21792191
for ( QgsFeatureList::iterator features = flist.begin(); features != flist.end(); features++ )
@@ -2188,19 +2200,9 @@ bool QgsPostgresProvider::addFeatures( QgsFeatureList &flist )
21882200

21892201
if ( primaryKeyType != "tid" )
21902202
{
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;
22042206
}
22052207

22062208
for ( int i = 0; i < fieldId.size(); i++ )
@@ -3111,8 +3113,7 @@ void QgsPostgresProvider::showMessageBox( const QString& title, const QString& t
31113113
message->showMessage();
31123114
}
31133115

3114-
void QgsPostgresProvider::showMessageBox( const QString& title,
3115-
const QStringList& text )
3116+
void QgsPostgresProvider::showMessageBox( const QString& title, const QStringList& text )
31163117
{
31173118
showMessageBox( title, text.join( "\n" ) );
31183119
}

0 commit comments

Comments
 (0)