@@ -1360,56 +1360,73 @@ bool QgsPostgresProvider::determinePrimaryKey()
1360
1360
return mValid ;
1361
1361
}
1362
1362
1363
- void QgsPostgresProvider::determinePrimaryKeyFromUriKeyColumn ()
1363
+ /* static */
1364
+ QStringList QgsPostgresProvider::parseUriKey ( const QString& key )
1364
1365
{
1365
- QString primaryKey = mUri .keyColumn ();
1366
- mPrimaryKeyType = pktUnknown;
1366
+ if ( key.isEmpty () ) return QStringList ();
1367
1367
1368
- if ( !primaryKey.isEmpty () )
1369
- {
1370
- QStringList cols;
1368
+ QStringList cols;
1371
1369
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 () )
1374
1376
{
1375
- int i = 1 ;
1376
- QString col;
1377
- while ( i < primaryKey.size () )
1377
+ if ( key[i] == ' "' )
1378
1378
{
1379
- if ( primaryKey[i ] == ' "' )
1379
+ if ( i + 1 < key. size () && key[i+ 1 ] == ' "' )
1380
1380
{
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 = " " ;
1389
1387
1390
- if ( ++i == primaryKey .size () )
1391
- break ;
1388
+ if ( ++i == key .size () )
1389
+ break ;
1392
1390
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 ;
1400
1397
}
1401
-
1402
- col += primaryKey[i++];
1403
1398
}
1399
+
1400
+ col += key[i++];
1404
1401
}
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 )
1410
1427
{
1411
- cols << primaryKey ;
1412
- primaryKey = quotedIdentifier ( primaryKey ) ;
1428
+ primaryKey += del + quotedIdentifier ( col ) ;
1429
+ del = " , " ;
1413
1430
}
1414
1431
1415
1432
Q_FOREACH ( const QString& col, cols )
@@ -3463,6 +3480,9 @@ QgsVectorLayerImport::ImportError QgsPostgresProvider::createEmptyLayer( const Q
3463
3480
QString primaryKey = dsUri.keyColumn ();
3464
3481
QString primaryKeyType;
3465
3482
3483
+ QStringList pkList;
3484
+ QStringList pkType;
3485
+
3466
3486
QString schemaTableName = " " ;
3467
3487
if ( !schemaName.isEmpty () )
3468
3488
{
@@ -3503,45 +3523,39 @@ QgsVectorLayerImport::ImportError QgsPostgresProvider::createEmptyLayer( const Q
3503
3523
}
3504
3524
else
3505
3525
{
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 )
3508
3528
{
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 )
3510
3532
{
3511
- // found, get the field type
3512
- QgsField fld = fields.at ( fldIdx );
3513
- if ( convertField ( fld, options ) )
3533
+ if ( fields[fldIdx].name () == col )
3514
3534
{
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
+ }
3516
3542
}
3517
3543
}
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;
3545
3559
}
3546
3560
}
3547
3561
@@ -3577,17 +3591,32 @@ QgsVectorLayerImport::ImportError QgsPostgresProvider::createEmptyLayer( const Q
3577
3591
throw PGException ( result );
3578
3592
}
3579
3593
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 )
3581
3597
{
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];
3586
3600
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 );
3591
3620
3592
3621
result = conn->PQexec ( sql );
3593
3622
if ( result.PQresultStatus () != PGRES_COMMAND_OK )
@@ -3678,9 +3707,25 @@ QgsVectorLayerImport::ImportError QgsPostgresProvider::createEmptyLayer( const Q
3678
3707
fld.setName ( fld.name ().toLower () );
3679
3708
}
3680
3709
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 )
3682
3727
{
3683
- oldToNewAttrIdxMap->insert ( fldIdx, 0 );
3728
+ oldToNewAttrIdxMap->insert ( fldIdx, pkIdx );
3684
3729
continue ;
3685
3730
}
3686
3731
0 commit comments