@@ -1360,56 +1360,73 @@ bool QgsPostgresProvider::determinePrimaryKey()
13601360 return mValid ;
13611361}
13621362
1363- void QgsPostgresProvider::determinePrimaryKeyFromUriKeyColumn ()
1363+ /* static */
1364+ QStringList QgsPostgresProvider::parseUriKey ( const QString& key )
13641365{
1365- QString primaryKey = mUri .keyColumn ();
1366- mPrimaryKeyType = pktUnknown;
1366+ if ( key.isEmpty () ) return QStringList ();
13671367
1368- if ( !primaryKey.isEmpty () )
1369- {
1370- QStringList cols;
1368+ QStringList cols;
13711369
1372- // remove quotes from key list
1373- if ( primaryKey.startsWith ( ' "' ) && primaryKey.endsWith ( ' "' ) )
1370+ // remove quotes from key list
1371+ if ( key.startsWith ( ' "' ) && key.endsWith ( ' "' ) )
1372+ {
1373+ int i = 1 ;
1374+ QString col;
1375+ while ( i < key.size () )
13741376 {
1375- int i = 1 ;
1376- QString col;
1377- while ( i < primaryKey.size () )
1377+ if ( key[i] == ' "' )
13781378 {
1379- if ( primaryKey[i ] == ' "' )
1379+ if ( i + 1 < key. size () && key[i+ 1 ] == ' "' )
13801380 {
1381- if ( i + 1 < primaryKey.size () && primaryKey[i+1 ] == ' "' )
1382- {
1383- i++;
1384- }
1385- else
1386- {
1387- cols << col;
1388- col = " " ;
1381+ i++;
1382+ }
1383+ else
1384+ {
1385+ cols << col;
1386+ col = " " ;
13891387
1390- if ( ++i == primaryKey .size () )
1391- break ;
1388+ if ( ++i == key .size () )
1389+ break ;
13921390
1393- Q_ASSERT ( primaryKey[i] == ' ,' );
1394- i++;
1395- Q_ASSERT ( primaryKey[i] == ' "' );
1396- i++;
1397- col = " " ;
1398- continue ;
1399- }
1391+ Q_ASSERT ( key[i] == ' ,' );
1392+ i++;
1393+ Q_ASSERT ( key[i] == ' "' );
1394+ i++;
1395+ col = " " ;
1396+ continue ;
14001397 }
1401-
1402- col += primaryKey[i++];
14031398 }
1399+
1400+ col += key[i++];
14041401 }
1405- else if ( primaryKey.contains ( ' ,' ) )
1406- {
1407- cols = primaryKey.split ( ' ,' );
1408- }
1409- else
1402+ }
1403+ else if ( key.contains ( ' ,' ) )
1404+ {
1405+ cols = key.split ( ' ,' );
1406+ }
1407+ else
1408+ {
1409+ cols << key;
1410+ }
1411+
1412+ return cols;
1413+ }
1414+
1415+ void QgsPostgresProvider::determinePrimaryKeyFromUriKeyColumn ()
1416+ {
1417+ QString primaryKey = mUri .keyColumn ();
1418+ mPrimaryKeyType = pktUnknown;
1419+
1420+ if ( !primaryKey.isEmpty () )
1421+ {
1422+ QStringList cols = parseUriKey ( primaryKey );
1423+
1424+ primaryKey = " " ;
1425+ QString del = " " ;
1426+ Q_FOREACH ( const QString& col, cols )
14101427 {
1411- cols << primaryKey ;
1412- primaryKey = quotedIdentifier ( primaryKey ) ;
1428+ primaryKey += del + quotedIdentifier ( col ) ;
1429+ del = " , " ;
14131430 }
14141431
14151432 Q_FOREACH ( const QString& col, cols )
@@ -3463,6 +3480,9 @@ QgsVectorLayerImport::ImportError QgsPostgresProvider::createEmptyLayer( const Q
34633480 QString primaryKey = dsUri.keyColumn ();
34643481 QString primaryKeyType;
34653482
3483+ QStringList pkList;
3484+ QStringList pkType;
3485+
34663486 QString schemaTableName = " " ;
34673487 if ( !schemaName.isEmpty () )
34683488 {
@@ -3503,45 +3523,39 @@ QgsVectorLayerImport::ImportError QgsPostgresProvider::createEmptyLayer( const Q
35033523 }
35043524 else
35053525 {
3506- // search for the passed field
3507- for ( int fldIdx = 0 ; fldIdx < fields. count (); ++fldIdx )
3526+ pkList = parseUriKey ( primaryKey );
3527+ Q_FOREACH ( const QString& col, pkList )
35083528 {
3509- if ( fields.at ( fldIdx ).name () == primaryKey )
3529+ // search for the passed field
3530+ QString type;
3531+ for ( int fldIdx = 0 ; fldIdx < fields.count (); ++fldIdx )
35103532 {
3511- // found, get the field type
3512- QgsField fld = fields.at ( fldIdx );
3513- if ( convertField ( fld, options ) )
3533+ if ( fields[fldIdx].name () == col )
35143534 {
3515- primaryKeyType = fld.typeName ();
3535+ // found, get the field type
3536+ QgsField fld = fields[fldIdx];
3537+ if ( convertField ( fld, options ) )
3538+ {
3539+ type = fld.typeName ();
3540+ break ;
3541+ }
35163542 }
35173543 }
3518- }
3519- }
3520-
3521- // if the pk field doesn't exist yet, create a serial pk field
3522- // as it's autoincremental
3523- if ( primaryKeyType.isEmpty () )
3524- {
3525- primaryKeyType = " serial" ;
3526- #if 0
3527- // TODO: check the feature count to choose if create a serial8 pk field
3528- if ( layer->featureCount() > 0xffffffff )
3529- {
3530- primaryKeyType = "serial8";
3531- }
3532- #endif
3533- }
3534- else
3535- {
3536- // if the pk field's type is one of the postgres integer types,
3537- // use the equivalent autoincremental type (serialN)
3538- if ( primaryKeyType == " int2" || primaryKeyType == " int4" )
3539- {
3540- primaryKeyType = " serial" ;
3541- }
3542- else if ( primaryKeyType == " int8" )
3543- {
3544- primaryKeyType = " serial8" ;
3544+ if ( type.isEmpty () ) type = " serial" ;
3545+ else
3546+ {
3547+ // if the pk field's type is one of the postgres integer types,
3548+ // use the equivalent autoincremental type (serialN)
3549+ if ( primaryKeyType == " int2" || primaryKeyType == " int4" )
3550+ {
3551+ primaryKeyType = " serial" ;
3552+ }
3553+ else if ( primaryKeyType == " int8" )
3554+ {
3555+ primaryKeyType = " serial8" ;
3556+ }
3557+ }
3558+ pkType << type;
35453559 }
35463560 }
35473561
@@ -3577,17 +3591,32 @@ QgsVectorLayerImport::ImportError QgsPostgresProvider::createEmptyLayer( const Q
35773591 throw PGException ( result );
35783592 }
35793593
3580- if ( options && options->value ( " lowercaseFieldNames" , false ).toBool () )
3594+ sql = QString ( " CREATE TABLE %1(" ) .arg ( schemaTableName );
3595+ QString pk;
3596+ for ( int i = 0 ; i < pkList.size (); ++i )
35813597 {
3582- // convert primary key name to lowercase
3583- // this must happen after determining the field type of the primary key
3584- primaryKey = primaryKey.toLower ();
3585- }
3598+ QString col = pkList[i];
3599+ const QString& type = pkType[i];
35863600
3587- sql = QString ( " CREATE TABLE %1(%2 %3 PRIMARY KEY)" )
3588- .arg ( schemaTableName,
3589- quotedIdentifier ( primaryKey ),
3590- primaryKeyType );
3601+ if ( options && options->value ( " lowercaseFieldNames" , false ).toBool () )
3602+ {
3603+ col = col.toLower ();
3604+ }
3605+ else
3606+ {
3607+ col = quotedIdentifier ( col ); // no need to quote lowercase field
3608+ }
3609+
3610+ if ( i )
3611+ {
3612+ pk += " ," ;
3613+ sql += " ," ;
3614+ }
3615+
3616+ pk += col;
3617+ sql += col + " " + type;
3618+ }
3619+ sql += QString ( " , PRIMARY KEY (%1) )" ) .arg ( pk );
35913620
35923621 result = conn->PQexec ( sql );
35933622 if ( result.PQresultStatus () != PGRES_COMMAND_OK )
@@ -3678,9 +3707,25 @@ QgsVectorLayerImport::ImportError QgsPostgresProvider::createEmptyLayer( const Q
36783707 fld.setName ( fld.name ().toLower () );
36793708 }
36803709
3681- if ( fld.name () == primaryKey )
3710+ int pkIdx = -1 ;
3711+ for ( int i = 0 ; i < pkList.size (); ++i )
3712+ {
3713+ QString col = pkList[i];
3714+ if ( options && options->value ( " lowercaseFieldNames" , false ).toBool () )
3715+ {
3716+ // convert field name to lowercase (TODO: avoid doing this
3717+ // over and over)
3718+ col = col.toLower ();
3719+ }
3720+ if ( fld.name () == col )
3721+ {
3722+ pkIdx = i;
3723+ break ;
3724+ }
3725+ }
3726+ if ( pkIdx >= 0 )
36823727 {
3683- oldToNewAttrIdxMap->insert ( fldIdx, 0 );
3728+ oldToNewAttrIdxMap->insert ( fldIdx, pkIdx );
36843729 continue ;
36853730 }
36863731
0 commit comments