@@ -1377,56 +1377,73 @@ bool QgsPostgresProvider::determinePrimaryKey()
1377
1377
return mValid ;
1378
1378
}
1379
1379
1380
- void QgsPostgresProvider::determinePrimaryKeyFromUriKeyColumn ()
1380
+ /* static */
1381
+ QStringList QgsPostgresProvider::parseUriKey ( const QString& key )
1381
1382
{
1382
- QString primaryKey = mUri .keyColumn ();
1383
- mPrimaryKeyType = pktUnknown;
1383
+ if ( key.isEmpty () ) return QStringList ();
1384
1384
1385
- if ( !primaryKey.isEmpty () )
1386
- {
1387
- QStringList cols;
1385
+ QStringList cols;
1388
1386
1389
- // remove quotes from key list
1390
- if ( primaryKey.startsWith ( ' "' ) && primaryKey.endsWith ( ' "' ) )
1387
+ // remove quotes from key list
1388
+ if ( key.startsWith ( ' "' ) && key.endsWith ( ' "' ) )
1389
+ {
1390
+ int i = 1 ;
1391
+ QString col;
1392
+ while ( i < key.size () )
1391
1393
{
1392
- int i = 1 ;
1393
- QString col;
1394
- while ( i < primaryKey.size () )
1394
+ if ( key[i] == ' "' )
1395
1395
{
1396
- if ( primaryKey[i ] == ' "' )
1396
+ if ( i + 1 < key. size () && key[i+ 1 ] == ' "' )
1397
1397
{
1398
- if ( i + 1 < primaryKey.size () && primaryKey[i+1 ] == ' "' )
1399
- {
1400
- i++;
1401
- }
1402
- else
1403
- {
1404
- cols << col;
1405
- col = " " ;
1398
+ i++;
1399
+ }
1400
+ else
1401
+ {
1402
+ cols << col;
1403
+ col = " " ;
1406
1404
1407
- if ( ++i == primaryKey .size () )
1408
- break ;
1405
+ if ( ++i == key .size () )
1406
+ break ;
1409
1407
1410
- Q_ASSERT ( primaryKey[i] == ' ,' );
1411
- i++;
1412
- Q_ASSERT ( primaryKey[i] == ' "' );
1413
- i++;
1414
- col = " " ;
1415
- continue ;
1416
- }
1408
+ Q_ASSERT ( key[i] == ' ,' );
1409
+ i++;
1410
+ Q_ASSERT ( key[i] == ' "' );
1411
+ i++;
1412
+ col = " " ;
1413
+ continue ;
1417
1414
}
1418
-
1419
- col += primaryKey[i++];
1420
1415
}
1416
+
1417
+ col += key[i++];
1421
1418
}
1422
- else if ( primaryKey.contains ( ' ,' ) )
1423
- {
1424
- cols = primaryKey.split ( ' ,' );
1425
- }
1426
- else
1419
+ }
1420
+ else if ( key.contains ( ' ,' ) )
1421
+ {
1422
+ cols = key.split ( ' ,' );
1423
+ }
1424
+ else
1425
+ {
1426
+ cols << key;
1427
+ }
1428
+
1429
+ return cols;
1430
+ }
1431
+
1432
+ void QgsPostgresProvider::determinePrimaryKeyFromUriKeyColumn ()
1433
+ {
1434
+ QString primaryKey = mUri .keyColumn ();
1435
+ mPrimaryKeyType = pktUnknown;
1436
+
1437
+ if ( !primaryKey.isEmpty () )
1438
+ {
1439
+ QStringList cols = parseUriKey ( primaryKey );
1440
+
1441
+ primaryKey = " " ;
1442
+ QString del = " " ;
1443
+ Q_FOREACH ( const QString& col, cols )
1427
1444
{
1428
- cols << primaryKey ;
1429
- primaryKey = quotedIdentifier ( primaryKey ) ;
1445
+ primaryKey += del + quotedIdentifier ( col ) ;
1446
+ del = " , " ;
1430
1447
}
1431
1448
1432
1449
Q_FOREACH ( const QString& col, cols )
@@ -3483,6 +3500,9 @@ QgsVectorLayerImport::ImportError QgsPostgresProvider::createEmptyLayer(
3483
3500
QString primaryKey = dsUri.keyColumn ();
3484
3501
QString primaryKeyType;
3485
3502
3503
+ QStringList pkList;
3504
+ QStringList pkType;
3505
+
3486
3506
QString schemaTableName = " " ;
3487
3507
if ( !schemaName.isEmpty () )
3488
3508
{
@@ -3523,45 +3543,39 @@ QgsVectorLayerImport::ImportError QgsPostgresProvider::createEmptyLayer(
3523
3543
}
3524
3544
else
3525
3545
{
3526
- // search for the passed field
3527
- for ( int fldIdx = 0 ; fldIdx < fields. count (); ++fldIdx )
3546
+ pkList = parseUriKey ( primaryKey );
3547
+ Q_FOREACH ( const QString& col, pkList )
3528
3548
{
3529
- if ( fields[fldIdx].name () == primaryKey )
3549
+ // search for the passed field
3550
+ QString type;
3551
+ for ( int fldIdx = 0 ; fldIdx < fields.count (); ++fldIdx )
3530
3552
{
3531
- // found, get the field type
3532
- QgsField fld = fields[fldIdx];
3533
- if ( convertField ( fld, options ) )
3553
+ if ( fields[fldIdx].name () == col )
3534
3554
{
3535
- primaryKeyType = fld.typeName ();
3555
+ // found, get the field type
3556
+ QgsField fld = fields[fldIdx];
3557
+ if ( convertField ( fld, options ) )
3558
+ {
3559
+ type = fld.typeName ();
3560
+ break ;
3561
+ }
3536
3562
}
3537
3563
}
3538
- }
3539
- }
3540
-
3541
- // if the pk field doesn't exist yet, create a serial pk field
3542
- // as it's autoincremental
3543
- if ( primaryKeyType.isEmpty () )
3544
- {
3545
- primaryKeyType = " serial" ;
3546
- #if 0
3547
- // TODO: check the feature count to choose if create a serial8 pk field
3548
- if ( layer->featureCount() > 0xffffffff )
3549
- {
3550
- primaryKeyType = "serial8";
3551
- }
3552
- #endif
3553
- }
3554
- else
3555
- {
3556
- // if the pk field's type is one of the postgres integer types,
3557
- // use the equivalent autoincremental type (serialN)
3558
- if ( primaryKeyType == " int2" || primaryKeyType == " int4" )
3559
- {
3560
- primaryKeyType = " serial" ;
3561
- }
3562
- else if ( primaryKeyType == " int8" )
3563
- {
3564
- primaryKeyType = " serial8" ;
3564
+ if ( type.isEmpty () ) type = " serial" ;
3565
+ else
3566
+ {
3567
+ // if the pk field's type is one of the postgres integer types,
3568
+ // use the equivalent autoincremental type (serialN)
3569
+ if ( primaryKeyType == " int2" || primaryKeyType == " int4" )
3570
+ {
3571
+ primaryKeyType = " serial" ;
3572
+ }
3573
+ else if ( primaryKeyType == " int8" )
3574
+ {
3575
+ primaryKeyType = " serial8" ;
3576
+ }
3577
+ }
3578
+ pkType << type;
3565
3579
}
3566
3580
}
3567
3581
@@ -3597,17 +3611,32 @@ QgsVectorLayerImport::ImportError QgsPostgresProvider::createEmptyLayer(
3597
3611
throw PGException ( result );
3598
3612
}
3599
3613
3600
- if ( options && options->value ( " lowercaseFieldNames" , false ).toBool () )
3614
+ sql = QString ( " CREATE TABLE %1(" ) .arg ( schemaTableName );
3615
+ QString pk;
3616
+ for ( int i = 0 ; i < pkList.size (); ++i )
3601
3617
{
3602
- // convert primary key name to lowercase
3603
- // this must happen after determining the field type of the primary key
3604
- primaryKey = primaryKey.toLower ();
3605
- }
3618
+ QString col = pkList[i];
3619
+ const QString& type = pkType[i];
3606
3620
3607
- sql = QString ( " CREATE TABLE %1(%2 %3 PRIMARY KEY)" )
3608
- .arg ( schemaTableName,
3609
- quotedIdentifier ( primaryKey ),
3610
- primaryKeyType );
3621
+ if ( options && options->value ( " lowercaseFieldNames" , false ).toBool () )
3622
+ {
3623
+ col = col.toLower ();
3624
+ }
3625
+ else
3626
+ {
3627
+ col = quotedIdentifier ( col ); // no need to quote lowercase field
3628
+ }
3629
+
3630
+ if ( i )
3631
+ {
3632
+ pk += " ," ;
3633
+ sql += " ," ;
3634
+ }
3635
+
3636
+ pk += col;
3637
+ sql += col + " " + type;
3638
+ }
3639
+ sql += QString ( " , PRIMARY KEY (%1) )" ) .arg ( pk );
3611
3640
3612
3641
result = conn->PQexec ( sql );
3613
3642
if ( result.PQresultStatus () != PGRES_COMMAND_OK )
@@ -3698,9 +3727,25 @@ QgsVectorLayerImport::ImportError QgsPostgresProvider::createEmptyLayer(
3698
3727
fld.setName ( fld.name ().toLower () );
3699
3728
}
3700
3729
3701
- if ( fld.name () == primaryKey )
3730
+ int pkIdx = -1 ;
3731
+ for ( int i = 0 ; i < pkList.size (); ++i )
3732
+ {
3733
+ QString col = pkList[i];
3734
+ if ( options && options->value ( " lowercaseFieldNames" , false ).toBool () )
3735
+ {
3736
+ // convert field name to lowercase (TODO: avoid doing this
3737
+ // over and over)
3738
+ col = col.toLower ();
3739
+ }
3740
+ if ( fld.name () == col )
3741
+ {
3742
+ pkIdx = i;
3743
+ break ;
3744
+ }
3745
+ }
3746
+ if ( pkIdx >= 0 )
3702
3747
{
3703
- oldToNewAttrIdxMap->insert ( fldIdx, 0 );
3748
+ oldToNewAttrIdxMap->insert ( fldIdx, pkIdx );
3704
3749
continue ;
3705
3750
}
3706
3751
0 commit comments