@@ -63,7 +63,9 @@ const QString POSTGRES_DESCRIPTION = "PostgreSQL/PostGIS data provider";
63
63
64
64
65
65
QgsPostgresProvider::QgsPostgresProvider (QString const & uri)
66
- : QgsVectorDataProvider(uri), geomType(QGis::WKBUnknown)
66
+ : QgsVectorDataProvider(uri),
67
+ geomType(QGis::WKBUnknown),
68
+ gotPostgisVersion(FALSE )
67
69
{
68
70
// assume this is a valid layer until we determine otherwise
69
71
valid = true ;
@@ -1457,8 +1459,31 @@ bool QgsPostgresProvider::addFeature(QgsFeature* f, int primaryKeyHighWater)
1457
1459
<< " ." << std::endl;
1458
1460
#endif
1459
1461
1460
- if (f)
1462
+ if (f)
1461
1463
{
1464
+ // Determine which insertion method to use for WKB
1465
+ // PostGIS 1.0+ uses BYTEA
1466
+ // earlier versions use HEX
1467
+ bool useWkbHex (FALSE );
1468
+
1469
+ if (!gotPostgisVersion)
1470
+ {
1471
+ postgisVersion (connection);
1472
+ }
1473
+
1474
+ #ifdef QGISDEBUG
1475
+ std::cout << " QgsPostgresProvider::addFeature: PostGIS version is "
1476
+ << " major: " << postgisVersionMajor
1477
+ << " , minor: " << postgisVersionMinor
1478
+ << " ." << std::endl;
1479
+ #endif
1480
+
1481
+ if (postgisVersionMajor < 1 )
1482
+ {
1483
+ useWkbHex = TRUE ;
1484
+ }
1485
+
1486
+ // Start building insert string
1462
1487
QString insert (" INSERT INTO " );
1463
1488
insert+=mSchemaTableName ;
1464
1489
insert+=" (" ;
@@ -1524,12 +1549,27 @@ bool QgsPostgresProvider::addFeature(QgsFeature* f, int primaryKeyHighWater)
1524
1549
1525
1550
insert+=" ) VALUES (GeomFromWKB('" ;
1526
1551
1527
- // add the wkb geometry to the insert statement
1528
- unsigned char * geom= f->getGeometry ();
1529
- for (int i=0 ;i< f->getGeometrySize ();++i)
1552
+ // Add the WKB geometry to the INSERT statement
1553
+ unsigned char * geom = f->getGeometry ();
1554
+ for (int i=0 ; i < f->getGeometrySize (); ++i)
1530
1555
{
1531
- // Postgis 1.0 wants bytea instead of hex
1532
- QString oct = QString::number ((int )geom[i], 8 );
1556
+ if (useWkbHex)
1557
+ {
1558
+ // PostGIS < 1.0 wants hex
1559
+ QString hex = QString::number ((int ) geom[i], 16 ).upper ();
1560
+
1561
+ if (hex.length () == 1 )
1562
+ {
1563
+ hex = " 0" + hex;
1564
+ }
1565
+
1566
+ insert += hex;
1567
+ }
1568
+ else
1569
+ {
1570
+ // Postgis 1.0 wants bytea
1571
+ QString oct = QString::number ((int ) geom[i], 8 );
1572
+
1533
1573
if (oct.length ()==3 )
1534
1574
{
1535
1575
oct=" \\\\ " +oct;
@@ -1542,9 +1582,19 @@ bool QgsPostgresProvider::addFeature(QgsFeature* f, int primaryKeyHighWater)
1542
1582
{
1543
1583
oct=" \\\\ 0" +oct;
1544
1584
}
1545
- insert+=oct;
1585
+
1586
+ insert += oct;
1587
+ }
1588
+ }
1589
+
1590
+ if (useWkbHex)
1591
+ {
1592
+ insert += " '," +srid+" )" ;
1593
+ }
1594
+ else
1595
+ {
1596
+ insert += " ::bytea'," +srid+" )" ;
1546
1597
}
1547
- insert+=" ::bytea'," +srid+" )" ;
1548
1598
1549
1599
// add the primary key value to the insert statement
1550
1600
insert += " ," ;
@@ -1695,20 +1745,31 @@ bool QgsPostgresProvider::hasGEOS(PGconn *connection){
1695
1745
// get geos capability
1696
1746
return geosAvailable;
1697
1747
}
1748
+
1698
1749
/* Functions for determining available features in postGIS */
1699
- QString QgsPostgresProvider::postgisVersion (PGconn *connection){
1750
+ QString QgsPostgresProvider::postgisVersion (PGconn *connection)
1751
+ {
1700
1752
PGresult *result = PQexec (connection, " select postgis_version()" );
1701
1753
postgisVersionInfo = PQgetvalue (result,0 ,0 );
1702
1754
#ifdef QGISDEBUG
1703
1755
std::cerr << " PostGIS version info: " << postgisVersionInfo.toLocal8Bit ().data () << std::endl;
1704
1756
#endif
1705
1757
PQclear (result);
1758
+
1759
+ QStringList postgisParts = QStringList::split (" " , postgisVersionInfo);
1760
+
1761
+ // Get major and minor version
1762
+ QStringList postgisVersionParts = QStringList::split (" ." , postgisParts[0 ]);
1763
+
1764
+ postgisVersionMajor = postgisVersionParts[0 ].toInt ();
1765
+ postgisVersionMinor = postgisVersionParts[1 ].toInt ();
1766
+
1706
1767
// assume no capabilities
1707
1768
geosAvailable = false ;
1708
1769
gistAvailable = false ;
1709
1770
projAvailable = false ;
1771
+
1710
1772
// parse out the capabilities and store them
1711
- QStringList postgisParts = QStringList::split (" " , postgisVersionInfo);
1712
1773
QStringList geos = postgisParts.grep (" GEOS" );
1713
1774
if (geos.size () == 1 ){
1714
1775
geosAvailable = (geos[0 ].find (" =1" ) > -1 );
@@ -1721,6 +1782,9 @@ QString QgsPostgresProvider::postgisVersion(PGconn *connection){
1721
1782
if (proj.size () == 1 ){
1722
1783
projAvailable = (proj[0 ].find (" =1" ) > -1 );
1723
1784
}
1785
+
1786
+ gotPostgisVersion = TRUE ;
1787
+
1724
1788
return postgisVersionInfo;
1725
1789
}
1726
1790
@@ -1882,9 +1946,33 @@ bool QgsPostgresProvider::changeGeometryValues(std::map<int, QgsGeometry> & geom
1882
1946
std::cerr << " QgsPostgresProvider::changeGeometryValues: entering."
1883
1947
<< std::endl;
1884
1948
#endif
1885
-
1886
- bool returnvalue=true ;
1887
-
1949
+
1950
+ bool returnvalue = true ;
1951
+
1952
+ // Determine which insertion method to use for WKB
1953
+ // PostGIS 1.0+ uses BYTEA
1954
+ // earlier versions use HEX
1955
+ bool useWkbHex (FALSE );
1956
+
1957
+ if (!gotPostgisVersion)
1958
+ {
1959
+ postgisVersion (connection);
1960
+ }
1961
+
1962
+ #ifdef QGISDEBUG
1963
+ std::cout << " QgsPostgresProvider::addFeature: PostGIS version is "
1964
+ << " major: " << postgisVersionMajor
1965
+ << " , minor: " << postgisVersionMinor
1966
+ << " ." << std::endl;
1967
+ #endif
1968
+
1969
+ if (postgisVersionMajor < 1 )
1970
+ {
1971
+ useWkbHex = TRUE ;
1972
+ }
1973
+
1974
+ // Start the PostGIS transaction
1975
+
1888
1976
PQexec (connection," BEGIN" );
1889
1977
1890
1978
for (std::map<int , QgsGeometry>::const_iterator iter = geometry_map.begin ();
@@ -1907,36 +1995,57 @@ bool QgsPostgresProvider::changeGeometryValues(std::map<int, QgsGeometry> & geom
1907
1995
1908
1996
QString sql = " UPDATE " + mSchemaTableName +" SET " +
1909
1997
geometryColumn + " =" ;
1910
-
1998
+
1911
1999
sql += " GeomFromWKB('" ;
1912
2000
1913
- // add the wkb geometry to the insert statement
2001
+ // Add the WKB geometry to the UPDATE statement
1914
2002
unsigned char * geom = iter->second .wkbBuffer ();
1915
-
1916
2003
for (int i=0 ; i < iter->second .wkbSize (); ++i)
1917
2004
{
1918
- // Postgis 1.0 wants bytea instead of hex
1919
- QString oct = QString::number ((int )geom[i], 8 );
1920
- if (oct.length ()==3 )
1921
- {
1922
- oct=" \\\\ " +oct;
1923
- }
1924
- else if (oct.length ()==1 )
1925
- {
1926
- oct=" \\\\ 00" +oct;
1927
- }
1928
- else if (oct.length ()==2 )
1929
- {
1930
- oct=" \\\\ 0" +oct;
1931
- }
1932
- sql += oct;
2005
+ if (useWkbHex)
2006
+ {
2007
+ // PostGIS < 1.0 wants hex
2008
+ QString hex = QString::number ((int ) geom[i], 16 ).upper ();
2009
+
2010
+ if (hex.length () == 1 )
2011
+ {
2012
+ hex = " 0" + hex;
2013
+ }
2014
+
2015
+ sql += hex;
2016
+ }
2017
+ else
2018
+ {
2019
+ // Postgis 1.0 wants bytea
2020
+ QString oct = QString::number ((int ) geom[i], 8 );
2021
+
2022
+ if (oct.length ()==3 )
2023
+ {
2024
+ oct=" \\\\ " +oct;
2025
+ }
2026
+ else if (oct.length ()==1 )
2027
+ {
2028
+ oct=" \\\\ 00" +oct;
2029
+ }
2030
+ else if (oct.length ()==2 )
2031
+ {
2032
+ oct=" \\\\ 0" +oct;
2033
+ }
2034
+
2035
+ sql += oct;
2036
+ }
1933
2037
}
1934
- sql+=" ::bytea'," +srid+" )" ;
1935
- sql+=" WHERE " +primaryKey+" =" +QString::number (iter->first );
1936
2038
1937
- #ifdef QGISDEBUG
1938
- qWarning (sql);
1939
- #endif
2039
+ if (useWkbHex)
2040
+ {
2041
+ sql += " '," +srid+" )" ;
2042
+ }
2043
+ else
2044
+ {
2045
+ sql += " ::bytea'," +srid+" )" ;
2046
+ }
2047
+
2048
+ sql += " WHERE " +primaryKey+" =" +QString::number (iter->first );
1940
2049
1941
2050
#ifdef QGISDEBUG
1942
2051
std::cerr << " QgsPostgresProvider::changeGeometryValues: Updating with '"
0 commit comments