Skip to content

Commit b85af12

Browse files
committedMay 12, 2013
postgres provider:
- move available table detection to thread - more progress messages
1 parent 4182baa commit b85af12

10 files changed

+357
-453
lines changed
 

‎src/providers/postgres/qgscolumntypethread.cpp

+45-11
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,20 @@ email : jef at norbit dot de
1616
***************************************************************************/
1717

1818
#include "qgscolumntypethread.h"
19+
#include "qgslogger.h"
1920

2021
#include <QMetaType>
2122

22-
QgsGeomColumnTypeThread::QgsGeomColumnTypeThread( QgsPostgresConn *conn, bool useEstimatedMetaData )
23+
QgsGeomColumnTypeThread::QgsGeomColumnTypeThread( QString name, bool useEstimatedMetaData, bool allowGeometrylessTables )
2324
: QThread()
24-
, mConn( conn )
25+
, mConn( 0 )
26+
, mName( name )
2527
, mUseEstimatedMetadata( useEstimatedMetaData )
28+
, mAllowGeometrylessTables( allowGeometrylessTables )
2629
{
2730
qRegisterMetaType<QgsPostgresLayerProperty>( "QgsPostgresLayerProperty" );
2831
}
2932

30-
void QgsGeomColumnTypeThread::addGeometryColumn( QgsPostgresLayerProperty layerProperty )
31-
{
32-
layerProperties << layerProperty;
33-
}
34-
3533
void QgsGeomColumnTypeThread::stop()
3634
{
3735
if ( !mConn )
@@ -43,31 +41,67 @@ void QgsGeomColumnTypeThread::stop()
4341

4442
void QgsGeomColumnTypeThread::run()
4543
{
44+
QgsDataSourceURI uri = QgsPostgresConn::connUri( mName );
45+
mConn = QgsPostgresConn::connectDb( uri.connectionInfo(), true );
4646
if ( !mConn )
47+
{
48+
QgsDebugMsg( "Connection failed - " + uri.connectionInfo() );
4749
return;
50+
}
4851

4952
mStopped = false;
5053

54+
bool dontResolveType = QgsPostgresConn::dontResolveType( mName );
55+
56+
emit progressMessage( tr( "Retrieving tables of %1..." ).arg( mName ) );
57+
QVector<QgsPostgresLayerProperty> layerProperties;
58+
if ( !mConn->supportedLayers( layerProperties,
59+
QgsPostgresConn::geometryColumnsOnly( mName ),
60+
QgsPostgresConn::publicSchemaOnly( mName ),
61+
mAllowGeometrylessTables ) ||
62+
layerProperties.isEmpty() )
63+
{
64+
return;
65+
}
66+
5167
int i = 0;
5268
foreach ( QgsPostgresLayerProperty layerProperty, layerProperties )
5369
{
5470
if ( !mStopped )
5571
{
5672
emit progress( i++, layerProperties.size() );
57-
emit progressMessage( tr( "Scanning column %1.%2.%3..." ).arg( layerProperty.schemaName ).arg( layerProperty.tableName ).arg( layerProperty.geometryColName ) );
58-
mConn->retrieveLayerTypes( layerProperty, mUseEstimatedMetadata );
73+
emit progressMessage( tr( "Scanning column %1.%2.%3..." )
74+
.arg( layerProperty.schemaName )
75+
.arg( layerProperty.tableName )
76+
.arg( layerProperty.geometryColName ) );
77+
78+
if ( !layerProperty.geometryColName.isNull() &&
79+
( layerProperty.types.value( 0, QGis::WKBUnknown ) == QGis::WKBUnknown ||
80+
layerProperty.srids.value( 0, 0 ) == 0 ) )
81+
{
82+
if ( dontResolveType )
83+
{
84+
QgsDebugMsg( QString( "skipping column %1.%2 without type constraint" ).arg( layerProperty.schemaName ).arg( layerProperty.tableName ) );
85+
continue;
86+
}
87+
88+
mConn->retrieveLayerTypes( layerProperty, mUseEstimatedMetadata );
89+
}
5990
}
6091

6192
if ( mStopped )
6293
{
63-
layerProperty.type = "";
64-
layerProperty.srid = "";
94+
layerProperty.types.clear();
95+
layerProperty.srids.clear();
6596
}
6697

6798
// Now tell the layer list dialog box...
6899
emit setLayerType( layerProperty );
69100
}
70101

102+
emit progress( 0, 0 );
103+
emit progressMessage( tr( "Table retrieval finished." ) );
104+
71105
mConn->disconnect();
72106
mConn = 0;
73107
}

‎src/providers/postgres/qgscolumntypethread.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class QgsGeomColumnTypeThread : public QThread
2828
{
2929
Q_OBJECT
3030
public:
31-
QgsGeomColumnTypeThread( QgsPostgresConn *conn, bool useEstimatedMetaData );
31+
QgsGeomColumnTypeThread( QString connName, bool useEstimatedMetaData, bool allowGeometrylessTables );
3232

3333
// These functions get the layer types and pass that information out
3434
// by emitting the setLayerType() signal.
@@ -40,14 +40,15 @@ class QgsGeomColumnTypeThread : public QThread
4040
void progressMessage( QString );
4141

4242
public slots:
43-
void addGeometryColumn( QgsPostgresLayerProperty layerProperty );
4443
void stop();
4544

4645
private:
4746
QgsGeomColumnTypeThread() {}
4847

4948
QgsPostgresConn *mConn;
49+
QString mName;
5050
bool mUseEstimatedMetadata;
51+
bool mAllowGeometrylessTables;
5152
bool mStopped;
5253
QList<QgsPostgresLayerProperty> layerProperties;
5354
};

‎src/providers/postgres/qgspgsourceselect.cpp

+25-110
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,18 @@ QgsPgSourceSelect::QgsPgSourceSelect( QWidget *parent, Qt::WFlags fl, bool manag
120120
: QDialog( parent, fl )
121121
, mManagerMode( managerMode )
122122
, mEmbeddedMode( embeddedMode )
123-
, mColumnTypeThread( NULL )
123+
, mColumnTypeThread( 0 )
124124
{
125125
setupUi( this );
126126

127127
if ( mEmbeddedMode )
128128
{
129129
buttonBox->button( QDialogButtonBox::Close )->hide();
130130
}
131+
else
132+
{
133+
setWindowTitle( tr( "Add PostGIS Table(s)" ) );
134+
}
131135

132136
mAddButton = new QPushButton( tr( "&Add" ) );
133137
mAddButton->setEnabled( false );
@@ -352,7 +356,7 @@ void QgsPgSourceSelect::on_mSearchModeComboBox_currentIndexChanged( const QStrin
352356
void QgsPgSourceSelect::setLayerType( QgsPostgresLayerProperty layerProperty )
353357
{
354358
QgsDebugMsg( "entering." );
355-
mTableModel.setGeometryTypesForTable( layerProperty );
359+
mTableModel.addTableEntry( layerProperty );
356360
}
357361

358362
QgsPgSourceSelect::~QgsPgSourceSelect()
@@ -437,80 +441,21 @@ void QgsPgSourceSelect::on_btnConnect_clicked()
437441
mConnInfo = uri.connectionInfo();
438442
mUseEstimatedMetadata = uri.useEstimatedMetadata();
439443

440-
QgsPostgresConn *conn = QgsPostgresConn::connectDb( uri.connectionInfo(), true );
441-
if ( conn )
442-
{
443-
QApplication::setOverrideCursor( Qt::WaitCursor );
444-
445-
bool searchPublicOnly = QgsPostgresConn::publicSchemaOnly( cmbConnections->currentText() );
446-
bool searchGeometryColumnsOnly = QgsPostgresConn::geometryColumnsOnly( cmbConnections->currentText() );
447-
bool dontResolveType = QgsPostgresConn::dontResolveType( cmbConnections->currentText() );
448-
bool allowGeometrylessTables = cbxAllowGeometrylessTables->isChecked();
449-
450-
emit progressMessage( tr( "Retrieving tables from %1..." ).arg( cmbConnections->currentText() ) );
451-
452-
QVector<QgsPostgresLayerProperty> layers;
453-
if ( conn->supportedLayers( layers, searchGeometryColumnsOnly, searchPublicOnly, allowGeometrylessTables ) )
454-
{
455-
// Add the supported layers to the table
456-
foreach ( QgsPostgresLayerProperty layer, layers )
457-
{
458-
QString type = layer.type;
459-
QString srid = layer.srid;
460-
if ( !layer.geometryColName.isNull() )
461-
{
462-
if ( QgsPostgresConn::wkbTypeFromPostgis( type ) == QGis::WKBUnknown || srid.isEmpty() )
463-
{
464-
if ( dontResolveType )
465-
{
466-
QgsDebugMsg( QString( "skipping column %1.%2 without type constraint" ).arg( layer.schemaName ).arg( layer.tableName ) );
467-
continue;
468-
}
469-
470-
addSearchGeometryColumn( layer );
471-
type = "";
472-
srid = "";
473-
}
474-
}
475-
QgsDebugMsg( QString( "adding table %1.%2" ).arg( layer.schemaName ).arg( layer.tableName ) );
476-
477-
layer.type = type;
478-
layer.srid = srid;
479-
mTableModel.addTableEntry( layer );
480-
}
481-
482-
if ( mColumnTypeThread )
483-
{
484-
btnConnect->setText( tr( "Stop" ) );
485-
mColumnTypeThread->start();
486-
}
487-
}
444+
QApplication::setOverrideCursor( Qt::BusyCursor );
488445

489-
//if we have only one schema item, expand it by default
490-
int numTopLevelItems = mTableModel.invisibleRootItem()->rowCount();
491-
if ( numTopLevelItems < 2 || mTableModel.tableCount() < 20 )
492-
{
493-
//expand all the toplevel items
494-
for ( int i = 0; i < numTopLevelItems; ++i )
495-
{
496-
mTablesTreeView->expand( mProxyModel.mapFromSource( mTableModel.indexFromItem( mTableModel.invisibleRootItem()->child( i ) ) ) );
497-
}
498-
}
446+
mColumnTypeThread = new QgsGeomColumnTypeThread( cmbConnections->currentText(), mUseEstimatedMetadata, cbxAllowGeometrylessTables->isChecked() );
499447

500-
conn->disconnect();
448+
connect( mColumnTypeThread, SIGNAL( setLayerType( QgsPostgresLayerProperty ) ),
449+
this, SLOT( setLayerType( QgsPostgresLayerProperty ) ) );
450+
connect( mColumnTypeThread, SIGNAL( finished() ),
451+
this, SLOT( columnThreadFinished() ) );
452+
connect( mColumnTypeThread, SIGNAL( progress( int, int ) ),
453+
this, SIGNAL( progress( int, int ) ) );
454+
connect( mColumnTypeThread, SIGNAL( progressMessage( QString ) ),
455+
this, SIGNAL( progressMessage( QString ) ) );
501456

502-
if ( !mColumnTypeThread )
503-
{
504-
finishList();
505-
}
506-
}
507-
else
508-
{
509-
// Let user know we couldn't initialise the Postgres/PostGIS provider
510-
QMessageBox::warning( this,
511-
tr( "Postgres/PostGIS Provider" ),
512-
tr( "Could not open the Postgres/PostGIS Provider.\nCheck message log for possible errors." ) );
513-
}
457+
btnConnect->setText( tr( "Stop" ) );
458+
mColumnTypeThread->start();
514459
}
515460

516461
void QgsPgSourceSelect::finishList()
@@ -527,15 +472,6 @@ void QgsPgSourceSelect::finishList()
527472

528473
mTablesTreeView->sortByColumn( QgsPgTableModel::dbtmTable, Qt::AscendingOrder );
529474
mTablesTreeView->sortByColumn( QgsPgTableModel::dbtmSchema, Qt::AscendingOrder );
530-
531-
emit progress( 0, 0 );
532-
emit progressMessage( tr( "Table retrieval finished." ) );
533-
534-
if ( mTablesTreeView->model()->rowCount() == 0 )
535-
QMessageBox::information( this,
536-
tr( "Postgres/PostGIS Provider" ),
537-
tr( "No accessible tables or views found.\nCheck the message log for possible errors." ) );
538-
539475
}
540476

541477
void QgsPgSourceSelect::columnThreadFinished()
@@ -568,8 +504,14 @@ void QgsPgSourceSelect::setSql( const QModelIndex &index )
568504
QModelIndex idx = mProxyModel.mapToSource( index );
569505
QString tableName = mTableModel.itemFromIndex( idx.sibling( idx.row(), QgsPgTableModel::dbtmTable ) )->text();
570506

571-
QgsVectorLayer *vlayer = new QgsVectorLayer( mTableModel.layerURI( idx, mConnInfo, mUseEstimatedMetadata ), tableName, "postgres" );
507+
QString uri = mTableModel.layerURI( idx, mConnInfo, mUseEstimatedMetadata );
508+
if ( uri.isNull() )
509+
{
510+
QgsDebugMsg( "no uri" );
511+
return;
512+
}
572513

514+
QgsVectorLayer *vlayer = new QgsVectorLayer( uri, tableName, "postgres" );
573515
if ( !vlayer->isValid() )
574516
{
575517
delete vlayer;
@@ -587,33 +529,6 @@ void QgsPgSourceSelect::setSql( const QModelIndex &index )
587529
delete vlayer;
588530
}
589531

590-
void QgsPgSourceSelect::addSearchGeometryColumn( QgsPostgresLayerProperty layerProperty )
591-
{
592-
// store the column details and do the query in a thread
593-
if ( !mColumnTypeThread )
594-
{
595-
QgsPostgresConn *conn = QgsPostgresConn::connectDb( mConnInfo, true /* readonly */ );
596-
if ( conn )
597-
{
598-
599-
mColumnTypeThread = new QgsGeomColumnTypeThread( conn, mUseEstimatedMetadata );
600-
601-
connect( mColumnTypeThread, SIGNAL( setLayerType( QgsPostgresLayerProperty ) ),
602-
this, SLOT( setLayerType( QgsPostgresLayerProperty ) ) );
603-
connect( this, SIGNAL( addGeometryColumn( QgsPostgresLayerProperty ) ),
604-
mColumnTypeThread, SLOT( addGeometryColumn( QgsPostgresLayerProperty ) ) );
605-
connect( mColumnTypeThread, SIGNAL( finished() ),
606-
this, SLOT( columnThreadFinished() ) );
607-
connect( mColumnTypeThread, SIGNAL( progress( int, int ) ),
608-
this, SIGNAL( progress( int, int ) ) );
609-
connect( mColumnTypeThread, SIGNAL( progressMessage( QString ) ),
610-
this, SIGNAL( progressMessage( QString ) ) );
611-
}
612-
}
613-
614-
emit addGeometryColumn( layerProperty );
615-
}
616-
617532
QString QgsPgSourceSelect::fullDescription( QString schema, QString table, QString column, QString type )
618533
{
619534
QString full_desc = "";

‎src/providers/postgres/qgspgtablemodel.cpp

+99-156
Original file line numberDiff line numberDiff line change
@@ -42,104 +42,109 @@ QgsPgTableModel::~QgsPgTableModel()
4242

4343
void QgsPgTableModel::addTableEntry( QgsPostgresLayerProperty layerProperty )
4444
{
45-
QgsDebugMsg( QString( "%1.%2.%3 type=%4 geomType=%5 srid=%6 pk=%7 sql=%8" )
46-
.arg( layerProperty.schemaName )
47-
.arg( layerProperty.tableName )
48-
.arg( layerProperty.geometryColName )
49-
.arg( layerProperty.type )
50-
.arg( layerProperty.geometryColType )
51-
.arg( layerProperty.srid )
52-
.arg( layerProperty.pkCols.join( "," ) )
53-
.arg( layerProperty.sql ) );
45+
QgsDebugMsg( layerProperty.toString() );
5446

5547
// is there already a root item with the given scheme Name?
56-
QStandardItem *schemaItem;
57-
QList<QStandardItem*> schemaItems = findItems( layerProperty.schemaName, Qt::MatchExactly, dbtmSchema );
48+
QStandardItem *schemaItem = 0;
5849

59-
// there is already an item for this schema
60-
if ( schemaItems.size() > 0 )
50+
for ( int i = 0; i < layerProperty.size(); i++ )
6151
{
62-
schemaItem = schemaItems.at( dbtmSchema );
63-
}
64-
else
65-
{
66-
// create a new toplevel item for this schema
67-
schemaItem = new QStandardItem( layerProperty.schemaName );
68-
schemaItem->setFlags( Qt::ItemIsEnabled );
69-
invisibleRootItem()->setChild( invisibleRootItem()->rowCount(), schemaItem );
70-
}
71-
72-
QGis::WkbType wkbType = QgsPostgresConn::wkbTypeFromPostgis( layerProperty.type );
73-
if ( wkbType == QGis::WKBUnknown && layerProperty.geometryColName.isEmpty() )
74-
{
75-
wkbType = QGis::WKBNoGeometry;
76-
}
77-
78-
QList<QStandardItem*> childItemList;
52+
QGis::WkbType wkbType = layerProperty.types[ i ];
53+
int srid = layerProperty.srids[ i ];
54+
if ( wkbType == QGis::WKBUnknown && layerProperty.geometryColName.isEmpty() )
55+
{
56+
wkbType = QGis::WKBNoGeometry;
57+
}
7958

80-
QStandardItem *schemaNameItem = new QStandardItem( layerProperty.schemaName );
81-
schemaNameItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
59+
bool selectable = wkbType == QGis::WKBNoGeometry || ( wkbType != QGis::WKBUnknown && srid != 0 );
8260

83-
QStandardItem *typeItem = new QStandardItem( iconForWkbType( wkbType ),
84-
wkbType == QGis::WKBUnknown
85-
? tr( "Detecting..." )
86-
: QgsPostgresConn::displayStringForWkbType( wkbType ) );
87-
typeItem->setData( wkbType == QGis::WKBUnknown, Qt::UserRole + 1 );
88-
typeItem->setData( wkbType, Qt::UserRole + 2 );
61+
QStandardItem *schemaNameItem = new QStandardItem( layerProperty.schemaName );
62+
QStandardItem *typeItem = new QStandardItem( iconForWkbType( wkbType ), wkbType == QGis::WKBUnknown ? tr( "Select..." ) : QgsPostgresConn::displayStringForWkbType( wkbType ) );
63+
typeItem->setData( wkbType == QGis::WKBUnknown, Qt::UserRole + 1 );
64+
typeItem->setData( wkbType, Qt::UserRole + 2 );
65+
if ( wkbType == QGis::WKBUnknown )
66+
typeItem->setFlags( typeItem->flags() | Qt::ItemIsEditable );
8967

90-
QStandardItem *geomTypeItem = new QStandardItem( QgsPostgresConn::displayStringForGeomType( layerProperty.geometryColType ) );
68+
QStandardItem *geomTypeItem = new QStandardItem( QgsPostgresConn::displayStringForGeomType( layerProperty.geometryColType ) );
9169

92-
QStandardItem *tableItem = new QStandardItem( layerProperty.tableName );
93-
QStandardItem *geomItem = new QStandardItem( layerProperty.geometryColName );
94-
QStandardItem *sridItem = new QStandardItem( layerProperty.srid );
95-
sridItem->setEditable( false );
70+
QStandardItem *tableItem = new QStandardItem( layerProperty.tableName );
71+
QStandardItem *geomItem = new QStandardItem( layerProperty.geometryColName );
72+
QStandardItem *sridItem = new QStandardItem( wkbType != QGis::WKBNoGeometry ? QString::number( srid ) : "" );
73+
sridItem->setEditable( wkbType != QGis::WKBNoGeometry && srid == 0 );
74+
if ( sridItem->isEditable() )
75+
{
76+
sridItem->setText( tr( "Enter..." ) );
77+
sridItem->setFlags( sridItem->flags() | Qt::ItemIsEditable );
78+
}
9679

97-
QString pkCol = "";
98-
if ( layerProperty.pkCols.size() > 0 )
99-
{
100-
pkCol = layerProperty.pkCols[0];
101-
}
80+
QString pkCol = "";
81+
if ( layerProperty.pkCols.size() > 0 )
82+
{
83+
pkCol = layerProperty.pkCols[0];
84+
}
10285

103-
QStandardItem *pkItem = new QStandardItem( pkCol );
104-
if ( layerProperty.pkCols.size() > 1 )
105-
pkItem->setFlags( pkItem->flags() | Qt::ItemIsEditable );
106-
else
107-
pkItem->setFlags( pkItem->flags() & ~Qt::ItemIsEditable );
86+
QStandardItem *pkItem = new QStandardItem( pkCol );
87+
if ( layerProperty.pkCols.size() > 1 )
88+
pkItem->setFlags( pkItem->flags() | Qt::ItemIsEditable );
89+
else
90+
pkItem->setFlags( pkItem->flags() & ~Qt::ItemIsEditable );
10891

109-
pkItem->setData( layerProperty.pkCols, Qt::UserRole + 1 );
110-
pkItem->setData( pkCol, Qt::UserRole + 2 );
92+
pkItem->setData( layerProperty.pkCols, Qt::UserRole + 1 );
93+
pkItem->setData( pkCol, Qt::UserRole + 2 );
11194

112-
QStandardItem *selItem = new QStandardItem( "" );
113-
selItem->setFlags( selItem->flags() | Qt::ItemIsUserCheckable );
114-
selItem->setCheckState( Qt::Checked );
115-
selItem->setToolTip( tr( "Disable 'Fast Access to Features at ID' capability to force keeping the attribute table in memory (e.g. in case of expensive views)." ) );
95+
QStandardItem *selItem = new QStandardItem( "" );
96+
selItem->setFlags( selItem->flags() | Qt::ItemIsUserCheckable );
97+
selItem->setCheckState( Qt::Checked );
98+
selItem->setToolTip( tr( "Disable 'Fast Access to Features at ID' capability to force keeping the attribute table in memory (e.g. in case of expensive views)." ) );
11699

117-
QStandardItem* sqlItem = new QStandardItem( layerProperty.sql );
100+
QStandardItem* sqlItem = new QStandardItem( layerProperty.sql );
118101

119-
childItemList << schemaNameItem;
120-
childItemList << tableItem;
121-
childItemList << geomItem;
122-
childItemList << geomTypeItem;
123-
childItemList << typeItem;
124-
childItemList << sridItem;
125-
childItemList << pkItem;
126-
childItemList << selItem;
127-
childItemList << sqlItem;
102+
QList<QStandardItem*> childItemList;
128103

129-
bool detailsFromThread = wkbType == QGis::WKBUnknown ||
130-
( wkbType != QGis::WKBNoGeometry && layerProperty.srid.isEmpty() );
104+
childItemList << schemaNameItem;
105+
childItemList << tableItem;
106+
childItemList << geomItem;
107+
childItemList << geomTypeItem;
108+
childItemList << typeItem;
109+
childItemList << sridItem;
110+
childItemList << pkItem;
111+
childItemList << selItem;
112+
childItemList << sqlItem;
131113

132-
if ( detailsFromThread )
133-
{
134114
foreach ( QStandardItem *item, childItemList )
135115
{
136-
item->setFlags( item->flags() & ~( Qt::ItemIsSelectable | Qt::ItemIsEnabled ) );
116+
if ( selectable )
117+
{
118+
item->setFlags( item->flags() | Qt::ItemIsSelectable );
119+
}
120+
else
121+
{
122+
item->setFlags( item->flags() & ~Qt::ItemIsSelectable );
123+
}
124+
}
125+
126+
if ( !schemaItem )
127+
{
128+
QList<QStandardItem*> schemaItems = findItems( layerProperty.schemaName, Qt::MatchExactly, dbtmSchema );
129+
130+
// there is already an item for this schema
131+
if ( schemaItems.size() > 0 )
132+
{
133+
schemaItem = schemaItems.at( dbtmSchema );
134+
}
135+
else
136+
{
137+
// create a new toplevel item for this schema
138+
schemaItem = new QStandardItem( layerProperty.schemaName );
139+
schemaItem->setFlags( Qt::ItemIsEnabled );
140+
invisibleRootItem()->setChild( invisibleRootItem()->rowCount(), schemaItem );
141+
}
137142
}
138-
}
139143

140-
schemaItem->appendRow( childItemList );
144+
schemaItem->appendRow( childItemList );
141145

142-
++mTableCount;
146+
++mTableCount;
147+
}
143148
}
144149

145150
void QgsPgTableModel::setSql( const QModelIndex &index, const QString &sql )
@@ -204,84 +209,6 @@ void QgsPgTableModel::setSql( const QModelIndex &index, const QString &sql )
204209
}
205210
}
206211

207-
void QgsPgTableModel::setGeometryTypesForTable( QgsPostgresLayerProperty layerProperty )
208-
{
209-
QStringList typeList = layerProperty.type.split( ",", QString::SkipEmptyParts );
210-
QStringList sridList = layerProperty.srid.split( ",", QString::SkipEmptyParts );
211-
Q_ASSERT( typeList.size() == sridList.size() );
212-
213-
//find schema item and table item
214-
QStandardItem* schemaItem;
215-
QList<QStandardItem*> schemaItems = findItems( layerProperty.schemaName, Qt::MatchExactly, dbtmSchema );
216-
217-
if ( schemaItems.size() < 1 )
218-
{
219-
return;
220-
}
221-
222-
schemaItem = schemaItems.at( 0 );
223-
224-
int n = schemaItem->rowCount();
225-
for ( int i = 0; i < n; i++ )
226-
{
227-
QModelIndex currentChildIndex = indexFromItem( schemaItem->child( i, dbtmSchema ) );
228-
if ( !currentChildIndex.isValid() )
229-
{
230-
continue;
231-
}
232-
233-
QList<QStandardItem *> row;
234-
235-
for ( int j = 0; j < dbtmColumns; j++ )
236-
{
237-
row << itemFromIndex( currentChildIndex.sibling( i, j ) );
238-
}
239-
240-
if ( row[ dbtmTable ]->text() == layerProperty.tableName && row[ dbtmGeomCol ]->text() == layerProperty.geometryColName )
241-
{
242-
row[ dbtmSrid ]->setText( layerProperty.srid );
243-
244-
if ( typeList.isEmpty() )
245-
{
246-
row[ dbtmType ]->setText( tr( "Select..." ) );
247-
row[ dbtmType ]->setFlags( row[ dbtmType ]->flags() | Qt::ItemIsEditable );
248-
249-
row[ dbtmSrid ]->setText( tr( "Enter..." ) );
250-
row[ dbtmSrid ]->setFlags( row[ dbtmSrid ]->flags() | Qt::ItemIsEditable );
251-
252-
foreach ( QStandardItem *item, row )
253-
{
254-
item->setFlags( item->flags() | Qt::ItemIsEnabled );
255-
}
256-
}
257-
else
258-
{
259-
// update existing row
260-
QGis::WkbType wkbType = QgsPostgresConn::wkbTypeFromPostgis( typeList.at( 0 ) );
261-
262-
row[ dbtmType ]->setIcon( iconForWkbType( wkbType ) );
263-
row[ dbtmType ]->setText( QgsPostgresConn::displayStringForWkbType( wkbType ) );
264-
row[ dbtmType ]->setData( false, Qt::UserRole + 1 );
265-
row[ dbtmType ]->setData( wkbType, Qt::UserRole + 2 );
266-
267-
row[ dbtmSrid ]->setText( sridList.at( 0 ) );
268-
269-
foreach ( QStandardItem *item, row )
270-
{
271-
item->setFlags( item->flags() | Qt::ItemIsSelectable | Qt::ItemIsEnabled );
272-
}
273-
274-
for ( int j = 1; j < typeList.size(); j++ )
275-
{
276-
layerProperty.type = typeList[j];
277-
layerProperty.srid = sridList[j];
278-
addTableEntry( layerProperty );
279-
}
280-
}
281-
}
282-
}
283-
}
284-
285212
QIcon QgsPgTableModel::iconForWkbType( QGis::WkbType type )
286213
{
287214
switch ( type )
@@ -321,7 +248,10 @@ bool QgsPgTableModel::setData( const QModelIndex &idx, const QVariant &value, in
321248
bool ok = geomType != QGis::WKBUnknown;
322249

323250
if ( ok && geomType != QGis::WKBNoGeometry )
324-
idx.sibling( idx.row(), dbtmSrid ).data().toInt( &ok );
251+
{
252+
int srid = idx.sibling( idx.row(), dbtmSrid ).data().toInt( &ok );
253+
ok &= srid != 0;
254+
}
325255

326256
QStringList pkCols = idx.sibling( idx.row(), dbtmPkCol ).data( Qt::UserRole + 1 ).toStringList();
327257
if ( ok && pkCols.size() > 0 )
@@ -343,20 +273,29 @@ bool QgsPgTableModel::setData( const QModelIndex &idx, const QVariant &value, in
343273
QString QgsPgTableModel::layerURI( const QModelIndex &index, QString connInfo, bool useEstimatedMetadata )
344274
{
345275
if ( !index.isValid() )
276+
{
277+
QgsDebugMsg( "invalid index" );
346278
return QString::null;
279+
}
347280

348281
QGis::WkbType wkbType = ( QGis::WkbType ) itemFromIndex( index.sibling( index.row(), dbtmType ) )->data( Qt::UserRole + 2 ).toInt();
349282
if ( wkbType == QGis::WKBUnknown )
283+
{
284+
QgsDebugMsg( "unknown geometry type" );
350285
// no geometry type selected
351286
return QString::null;
287+
}
352288

353289
QStandardItem *pkItem = itemFromIndex( index.sibling( index.row(), dbtmPkCol ) );
354290
QString pkColumnName = pkItem->data( Qt::UserRole + 2 ).toString();
355291

356292
if ( pkItem->data( Qt::UserRole + 1 ).toStringList().size() > 0 &&
357293
!pkItem->data( Qt::UserRole + 1 ).toStringList().contains( pkColumnName ) )
294+
{
358295
// no valid primary candidate selected
296+
QgsDebugMsg( "no pk candidate selected" );
359297
return QString::null;
298+
}
360299

361300
QString schemaName = index.sibling( index.row(), dbtmSchema ).data( Qt::DisplayRole ).toString();
362301
QString tableName = index.sibling( index.row(), dbtmTable ).data( Qt::DisplayRole ).toString();
@@ -371,7 +310,10 @@ QString QgsPgTableModel::layerURI( const QModelIndex &index, QString connInfo, b
371310
bool ok;
372311
srid.toInt( &ok );
373312
if ( !ok )
313+
{
314+
QgsDebugMsg( "srid not numeric" );
374315
return QString::null;
316+
}
375317
}
376318

377319
bool selectAtId = itemFromIndex( index.sibling( index.row(), dbtmSelectAtId ) )->checkState() == Qt::Checked;
@@ -384,5 +326,6 @@ QString QgsPgTableModel::layerURI( const QModelIndex &index, QString connInfo, b
384326
uri.setSrid( srid );
385327
uri.disableSelectAtId( !selectAtId );
386328

329+
QgsDebugMsg( QString( "returning uri %1" ).arg( uri.uri() ) );
387330
return uri.uri();
388331
}

‎src/providers/postgres/qgspgtablemodel.h

+3-5
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
* (at your option) any later version. *
1515
* *
1616
***************************************************************************/
17-
17+
#ifndef QGSPGTABLEMODEL_H
18+
#define QGSPGTABLEMODEL_H
1819
#include <QStandardItemModel>
1920

2021
#include "qgis.h"
@@ -38,10 +39,6 @@ class QgsPgTableModel : public QStandardItemModel
3839
/**Sets an sql statement that belongs to a cell specified by a model index*/
3940
void setSql( const QModelIndex& index, const QString& sql );
4041

41-
/**Sets one or more geometry types to a row. In case of several types, additional rows are inserted.
42-
This is for tables where the type is dectected later by thread*/
43-
void setGeometryTypesForTable( QgsPostgresLayerProperty layerProperty );
44-
4542
/**Returns the number of tables in the model*/
4643
int tableCount() const { return mTableCount; }
4744

@@ -70,3 +67,4 @@ class QgsPgTableModel : public QStandardItemModel
7067
int mTableCount;
7168
};
7269

70+
#endif // QGSPGTABLEMODEL_H

‎src/providers/postgres/qgspostgresconn.cpp

+51-62
Original file line numberDiff line numberDiff line change
@@ -389,11 +389,13 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
389389
.arg( relkind ) );
390390

391391
layerProperty.pkCols.clear();
392-
layerProperty.type = type;
393392
layerProperty.schemaName = schemaName;
394393
layerProperty.tableName = tableName;
395394
layerProperty.geometryColName = column;
396395
layerProperty.geometryColType = columnType;
396+
layerProperty.types = QList<QGis::WkbType>() << ( QgsPostgresConn::wkbTypeFromPostgis( type ) );
397+
layerProperty.srids = QList<int>() << srid.toInt();
398+
layerProperty.sql = "";
397399

398400
if ( relkind == "v" )
399401
{
@@ -405,9 +407,6 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
405407
}
406408
}
407409

408-
layerProperty.srid = srid;
409-
layerProperty.sql = "";
410-
411410
mLayersSupported << layerProperty;
412411
nColumns++;
413412
}
@@ -493,7 +492,8 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
493492

494493
QgsDebugMsg( QString( "%1.%2.%3: %4" ).arg( schemaName ).arg( tableName ).arg( column ).arg( relkind ) );
495494

496-
layerProperty.type = QString::null;
495+
layerProperty.types.clear();
496+
layerProperty.srids.clear();
497497
layerProperty.schemaName = schemaName;
498498
layerProperty.tableName = tableName;
499499
layerProperty.geometryColName = column;
@@ -531,7 +531,6 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
531531
}
532532
}
533533

534-
535534
if ( allowGeometrylessTables )
536535
{
537536
QString sql = "SELECT "
@@ -570,13 +569,13 @@ bool QgsPostgresConn::getTableInfo( bool searchGeometryColumnsOnly, bool searchP
570569

571570
QgsDebugMsg( QString( "%1.%2: %3" ).arg( schema ).arg( table ).arg( relkind ) );
572571

573-
layerProperty.type = QString::null;
572+
layerProperty.types = QList<QGis::WkbType>() << QGis::WKBUnknown;
573+
layerProperty.srids = QList<int>() << 0;
574574
layerProperty.schemaName = schema;
575575
layerProperty.tableName = table;
576576
layerProperty.geometryColName = QString::null;
577577
layerProperty.geometryColType = sctNone;
578578
layerProperty.pkCols = relkind == "v" ? pkCandidates( schema, table ) : QStringList();
579-
layerProperty.srid = "";
580579
layerProperty.sql = "";
581580

582581
mLayersSupported << layerProperty;
@@ -1095,66 +1094,56 @@ void QgsPostgresConn::retrieveLayerTypes( QgsPostgresLayerProperty &layerPropert
10951094
table = layerProperty.tableName;
10961095
}
10971096

1098-
1099-
// our estimatation ignores that a where clause might restrict the feature type or srid
1100-
if ( useEstimatedMetadata )
1101-
{
1102-
table = QString( "(SELECT %1 FROM %2 WHERE %1 IS NOT NULL%3 LIMIT %4) AS t" )
1103-
.arg( quotedIdentifier( layerProperty.geometryColName ) )
1104-
.arg( table )
1105-
.arg( layerProperty.sql.isEmpty() ? "" : QString( " AND (%1)" ).arg( layerProperty.sql ) )
1106-
.arg( sGeomTypeSelectLimit );
1107-
}
1108-
else if ( !layerProperty.sql.isEmpty() )
1109-
{
1110-
table += QString( " WHERE %1" ).arg( layerProperty.sql );
1111-
}
1112-
1113-
QString query = QString( "SELECT DISTINCT"
1114-
" CASE"
1115-
" WHEN %1 THEN 'POINT'"
1116-
" WHEN %2 THEN 'LINESTRING'"
1117-
" WHEN %3 THEN 'POLYGON'"
1118-
" END,"
1119-
" %4(%5%6)"
1120-
" FROM %7" )
1121-
.arg( postgisTypeFilter( layerProperty.geometryColName, QGis::WKBPoint, layerProperty.geometryColType == sctGeography ) )
1122-
.arg( postgisTypeFilter( layerProperty.geometryColName, QGis::WKBLineString, layerProperty.geometryColType == sctGeography ) )
1123-
.arg( postgisTypeFilter( layerProperty.geometryColName, QGis::WKBPolygon, layerProperty.geometryColType == sctGeography ) )
1124-
.arg( majorVersion() < 2 ? "srid" : "st_srid" )
1125-
.arg( quotedIdentifier( layerProperty.geometryColName ) )
1126-
.arg( layerProperty.geometryColType == sctGeography ? "::geometry" : "" )
1127-
.arg( table );
1128-
1129-
QgsDebugMsg( "Retrieving geometry types: " + query );
1130-
1131-
QgsPostgresResult gresult = PQexec( query );
1132-
1133-
QString type;
1134-
QString srid;
1135-
if ( gresult.PQresultStatus() == PGRES_TUPLES_OK )
1097+
if ( !layerProperty.geometryColName.isEmpty() )
11361098
{
1137-
QStringList types;
1138-
QStringList srids;
1099+
// our estimatation ignores that a where clause might restrict the feature type or srid
1100+
if ( useEstimatedMetadata )
1101+
{
1102+
table = QString( "(SELECT %1 FROM %2 WHERE %1 IS NOT NULL%3 LIMIT %4) AS t" )
1103+
.arg( quotedIdentifier( layerProperty.geometryColName ) )
1104+
.arg( table )
1105+
.arg( layerProperty.sql.isEmpty() ? "" : QString( " AND (%1)" ).arg( layerProperty.sql ) )
1106+
.arg( sGeomTypeSelectLimit );
1107+
}
1108+
else if ( !layerProperty.sql.isEmpty() )
1109+
{
1110+
table += QString( " WHERE %1" ).arg( layerProperty.sql );
1111+
}
11391112

1140-
for ( int i = 0; i < gresult.PQntuples(); i++ )
1113+
QString query = QString( "SELECT DISTINCT"
1114+
" CASE"
1115+
" WHEN %1 THEN 'POINT'"
1116+
" WHEN %2 THEN 'LINESTRING'"
1117+
" WHEN %3 THEN 'POLYGON'"
1118+
" END,"
1119+
" %4(%5%6)"
1120+
" FROM %7" )
1121+
.arg( postgisTypeFilter( layerProperty.geometryColName, QGis::WKBPoint, layerProperty.geometryColType == sctGeography ) )
1122+
.arg( postgisTypeFilter( layerProperty.geometryColName, QGis::WKBLineString, layerProperty.geometryColType == sctGeography ) )
1123+
.arg( postgisTypeFilter( layerProperty.geometryColName, QGis::WKBPolygon, layerProperty.geometryColType == sctGeography ) )
1124+
.arg( majorVersion() < 2 ? "srid" : "st_srid" )
1125+
.arg( quotedIdentifier( layerProperty.geometryColName ) )
1126+
.arg( layerProperty.geometryColType == sctGeography ? "::geometry" : "" )
1127+
.arg( table );
1128+
1129+
QgsDebugMsg( "Retrieving geometry types: " + query );
1130+
1131+
QgsPostgresResult gresult = PQexec( query );
1132+
1133+
if ( gresult.PQresultStatus() == PGRES_TUPLES_OK )
11411134
{
1142-
QString type = gresult.PQgetvalue( i, 0 );
1143-
QString srid = gresult.PQgetvalue( i, 1 );
1144-
if ( type.isEmpty() )
1145-
continue;
1135+
for ( int i = 0; i < gresult.PQntuples(); i++ )
1136+
{
1137+
QString type = gresult.PQgetvalue( i, 0 );
1138+
QString srid = gresult.PQgetvalue( i, 1 );
1139+
if ( type.isEmpty() )
1140+
continue;
11461141

1147-
types << type;
1148-
srids << srid;
1142+
layerProperty.types << QgsPostgresConn::wkbTypeFromPostgis( type );
1143+
layerProperty.srids << srid.toInt();
1144+
}
11491145
}
1150-
1151-
type = types.join( "," );
1152-
srid = srids.join( "," );
11531146
}
1154-
1155-
QgsDebugMsg( QString( "type:%1 srid:%2" ).arg( type ).arg( srid ) );
1156-
layerProperty.type = type;
1157-
layerProperty.srid = srid;
11581147
}
11591148

11601149
void QgsPostgresConn::postgisWkbType( QGis::WkbType wkbType, QString &geometryType, int &dim )

‎src/providers/postgres/qgspostgresconn.h

+51-2
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,63 @@ enum QgsPostgresGeometryColumnType
4646
struct QgsPostgresLayerProperty
4747
{
4848
// Postgres/PostGIS layer properties
49-
QString type;
49+
QList<QGis::WkbType> types;
5050
QString schemaName;
5151
QString tableName;
5252
QString geometryColName;
5353
QgsPostgresGeometryColumnType geometryColType;
5454
QStringList pkCols;
55-
QString srid;
55+
QList<int> srids;
5656
QString sql;
57+
58+
int size() { Q_ASSERT( types.size() == srids.size() ); return types.size(); }
59+
60+
QgsPostgresLayerProperty at( int i )
61+
{
62+
QgsPostgresLayerProperty property;
63+
64+
Q_ASSERT( i >= 0 && i < size() );
65+
66+
property.types << types[ i ];
67+
property.srids << srids[ i ];
68+
property.schemaName = schemaName;
69+
property.tableName = tableName;
70+
property.geometryColName = geometryColName;
71+
property.geometryColType = geometryColType;
72+
property.pkCols = pkCols;
73+
property.sql = sql;
74+
75+
return property;
76+
}
77+
78+
#if QGISDEBUG
79+
QString toString()
80+
{
81+
QString typeString;
82+
foreach ( QGis::WkbType type, types )
83+
{
84+
if ( !typeString.isEmpty() )
85+
typeString += "|";
86+
typeString += QString::number( type );
87+
}
88+
QString sridString;
89+
foreach ( int srid, srids )
90+
{
91+
if ( !sridString.isEmpty() )
92+
sridString += "|";
93+
sridString += QString::number( srid );
94+
}
95+
96+
return QString( "%1.%2.%3 type=%4 srid=%5 pkCols=%6 sql=%7" )
97+
.arg( schemaName )
98+
.arg( tableName )
99+
.arg( geometryColName )
100+
.arg( typeString )
101+
.arg( sridString )
102+
.arg( pkCols.join( "|" ) )
103+
.arg( sql );
104+
}
105+
#endif
57106
};
58107

59108
class QgsPostgresResult

‎src/providers/postgres/qgspostgresdataitems.cpp

+64-92
Original file line numberDiff line numberDiff line change
@@ -73,106 +73,66 @@ void QgsPGConnectionItem::refresh()
7373
QVector<QgsDataItem*> QgsPGConnectionItem::createChildren()
7474
{
7575
QgsDebugMsg( "Entered" );
76-
QVector<QgsDataItem*> children;
77-
QgsDataSourceURI uri = QgsPostgresConn::connUri( mName );
7876

7977
mSchemaMap.clear();
8078

81-
mConn = QgsPostgresConn::connectDb( uri.connectionInfo(), true );
82-
if ( !mConn )
83-
return children;
84-
85-
QVector<QgsPostgresLayerProperty> layerProperties;
86-
if ( !mConn->supportedLayers( layerProperties,
87-
QgsPostgresConn::geometryColumnsOnly( mName ),
88-
QgsPostgresConn::publicSchemaOnly( mName ),
89-
QgsPostgresConn::allowGeometrylessTables( mName ) ) )
90-
{
91-
children.append( new QgsErrorItem( this, tr( "Failed to retrieve layers" ), mPath + "/error" ) );
92-
return children;
93-
}
94-
95-
if ( layerProperties.isEmpty() )
96-
{
97-
children.append( new QgsErrorItem( this, tr( "No layers found." ), mPath + "/error" ) );
98-
return children;
99-
}
100-
10179
stop();
10280

103-
bool dontResolveType = QgsPostgresConn::dontResolveType( mName );
104-
105-
foreach ( QgsPostgresLayerProperty layerProperty, layerProperties )
81+
if ( !mColumnTypeThread )
10682
{
107-
QgsPGSchemaItem *schemaItem = mSchemaMap.value( layerProperty.schemaName, 0 );
108-
if ( !schemaItem )
109-
{
110-
schemaItem = new QgsPGSchemaItem( this, layerProperty.schemaName, mPath + "/" + layerProperty.schemaName );
111-
children.append( schemaItem );
112-
mSchemaMap[ layerProperty.schemaName ] = schemaItem;
113-
}
114-
115-
if ( QgsPostgresConn::wkbTypeFromPostgis( layerProperty.type ) == QGis::WKBUnknown )
116-
{
117-
if ( !dontResolveType )
118-
{
119-
QgsDebugMsg( QString( "Skip column %1.%2.%3 without type constraint" ).arg( layerProperty.schemaName ).arg( layerProperty.tableName ).arg( layerProperty.geometryColName ) );
120-
continue;
121-
}
122-
123-
if ( !mColumnTypeThread )
124-
{
125-
QgsPostgresConn *conn = QgsPostgresConn::connectDb( uri.connectionInfo(), true /* readonly */ );
126-
if ( conn )
127-
{
128-
mColumnTypeThread = new QgsGeomColumnTypeThread( conn, true /* use estimated metadata */ );
129-
130-
connect( mColumnTypeThread, SIGNAL( setLayerType( QgsPostgresLayerProperty ) ),
131-
this, SLOT( setLayerType( QgsPostgresLayerProperty ) ) );
132-
connect( this, SIGNAL( addGeometryColumn( QgsPostgresLayerProperty ) ),
133-
mColumnTypeThread, SLOT( addGeometryColumn( QgsPostgresLayerProperty ) ) );
134-
}
135-
}
83+
mColumnTypeThread = new QgsGeomColumnTypeThread( mName, true /* useEstimatedMetadata */, QgsPostgresConn::allowGeometrylessTables( mName ) );
13684

137-
emit addGeometryColumn( layerProperty );
85+
connect( mColumnTypeThread, SIGNAL( setLayerType( QgsPostgresLayerProperty ) ),
86+
this, SLOT( setLayerType( QgsPostgresLayerProperty ) ) );
87+
connect( mColumnTypeThread, SIGNAL( started() ), this, SLOT( threadStarted() ) );
88+
connect( mColumnTypeThread, SIGNAL( finished() ), this, SLOT( threadFinished() ) );
13889

139-
continue;
90+
if ( QgsPGRootItem::sMainWindow )
91+
{
92+
connect( mColumnTypeThread, SIGNAL( progress( int, int ) ),
93+
QgsPGRootItem::sMainWindow, SLOT( showProgress( int, int ) ) );
94+
connect( mColumnTypeThread, SIGNAL( progressMessage( QString ) ),
95+
QgsPGRootItem::sMainWindow, SLOT( showStatusMessage( QString ) ) );
14096
}
141-
142-
schemaItem->addLayer( layerProperty );
14397
}
14498

14599
if ( mColumnTypeThread )
146100
mColumnTypeThread->start();
147101

148-
return children;
102+
return QVector<QgsDataItem*>();
149103
}
150104

151-
void QgsPGConnectionItem::setLayerType( QgsPostgresLayerProperty layerProperty )
105+
void QgsPGConnectionItem::threadStarted()
152106
{
153-
QgsPGSchemaItem *schemaItem = mSchemaMap.value( layerProperty.schemaName, 0 );
107+
QgsDebugMsg( "Entering." );
108+
qApp->setOverrideCursor( Qt::BusyCursor );
109+
}
154110

155-
if ( !schemaItem )
156-
{
157-
QgsDebugMsg( QString( "schema item for %1 not found." ).arg( layerProperty.schemaName ) );
158-
return;
159-
}
111+
void QgsPGConnectionItem::threadFinished()
112+
{
113+
QgsDebugMsg( "Entering." );
114+
qApp->restoreOverrideCursor();
115+
}
160116

161-
QStringList typeList = layerProperty.type.split( ",", QString::SkipEmptyParts );
162-
QStringList sridList = layerProperty.srid.split( ",", QString::SkipEmptyParts );
163-
Q_ASSERT( typeList.size() == sridList.size() );
117+
void QgsPGConnectionItem::setLayerType( QgsPostgresLayerProperty layerProperties )
118+
{
119+
QgsDebugMsg( layerProperties.toString() );
120+
QgsPGSchemaItem *schemaItem = mSchemaMap.value( layerProperties.schemaName, 0 );
164121

165-
for ( int i = 0 ; i < typeList.size(); i++ )
122+
for ( int i = 0; i < layerProperties.size(); i++ )
166123
{
167-
QGis::WkbType wkbType = QgsPostgresConn::wkbTypeFromPostgis( typeList[i] );
168-
if ( wkbType == QGis::WKBUnknown )
169-
{
170-
QgsDebugMsg( QString( "unsupported geometry type:%1" ).arg( typeList[i] ) );
124+
QgsPostgresLayerProperty layerProperty = layerProperties.at( i );
125+
126+
if ( layerProperty.types[0] == QGis::WKBUnknown && !layerProperty.geometryColName.isEmpty() )
171127
continue;
128+
129+
if ( !schemaItem )
130+
{
131+
schemaItem = new QgsPGSchemaItem( this, layerProperty.schemaName, mPath + "/" + layerProperty.schemaName );
132+
addChildItem( schemaItem, true );
133+
mSchemaMap[ layerProperty.schemaName ] = schemaItem;
172134
}
173135

174-
layerProperty.type = typeList[i];
175-
layerProperty.srid = sridList[i];
176136
schemaItem->addLayer( layerProperty );
177137
}
178138
}
@@ -185,7 +145,7 @@ bool QgsPGConnectionItem::equal( const QgsDataItem *other )
185145
}
186146

187147
const QgsPGConnectionItem *o = qobject_cast<const QgsPGConnectionItem *>( other );
188-
return ( mPath == o->mPath && mName == o->mName && o->connection() == connection() );
148+
return ( mPath == o->mPath && mName == o->mName );
189149
}
190150

191151
QList<QAction*> QgsPGConnectionItem::actions()
@@ -200,6 +160,10 @@ QList<QAction*> QgsPGConnectionItem::actions()
200160
connect( actionDelete, SIGNAL( triggered() ), this, SLOT( deleteConnection() ) );
201161
lst.append( actionDelete );
202162

163+
QAction* actionRefresh = new QAction( tr( "Refresh" ), this );
164+
connect( actionRefresh, SIGNAL( triggered() ), this, SLOT( refreshConnection() ) );
165+
lst.append( actionRefresh );
166+
203167
return lst;
204168
}
205169

@@ -220,6 +184,12 @@ void QgsPGConnectionItem::deleteConnection()
220184
mParent->refresh();
221185
}
222186

187+
void QgsPGConnectionItem::refreshConnection()
188+
{
189+
// the parent should be updated
190+
refresh();
191+
}
192+
223193
bool QgsPGConnectionItem::handleDrop( const QMimeData * data, Qt::DropAction )
224194
{
225195
if ( !QgsMimeDataUtils::isUriList( data ) )
@@ -301,6 +271,7 @@ QgsPGLayerItem::QgsPGLayerItem( QgsDataItem* parent, QString name, QString path,
301271
{
302272
mUri = createUri();
303273
mPopulated = true;
274+
Q_ASSERT( mLayerProperty.size() == 1 );
304275
}
305276

306277
QgsPGLayerItem::~QgsPGLayerItem()
@@ -344,12 +315,10 @@ QString QgsPGLayerItem::createUri()
344315
return QString::null;
345316
}
346317

347-
QgsDebugMsg( QString( "connInfo: %1" ).arg( connItem->connection()->connInfo() ) );
348-
349-
QgsDataSourceURI uri( connItem->connection()->connInfo() );
318+
QgsDataSourceURI uri( QgsPostgresConn::connUri( connItem->name() ).connectionInfo() );
350319
uri.setDataSource( mLayerProperty.schemaName, mLayerProperty.tableName, mLayerProperty.geometryColName, mLayerProperty.sql, pkColName );
351-
uri.setSrid( mLayerProperty.srid );
352-
uri.setWkbType( QgsPostgresConn::wkbTypeFromPostgis( mLayerProperty.type ) );
320+
uri.setSrid( QString::number( mLayerProperty.srids[0] ) );
321+
uri.setWkbType( mLayerProperty.types[0] );
353322
QgsDebugMsg( QString( "layer uri: %1" ).arg( uri.uri() ) );
354323
return uri.uri();
355324
}
@@ -373,8 +342,8 @@ QgsPGSchemaItem::~QgsPGSchemaItem()
373342

374343
void QgsPGSchemaItem::addLayer( QgsPostgresLayerProperty layerProperty )
375344
{
376-
QGis::WkbType wkbType = QgsPostgresConn::wkbTypeFromPostgis( layerProperty.type );
377-
QString tip = tr( "%1 as %2 in %3" ).arg( layerProperty.geometryColName ).arg( QgsPostgresConn::displayStringForWkbType( wkbType ) ).arg( layerProperty.srid );
345+
QGis::WkbType wkbType = layerProperty.types[0];
346+
QString tip = tr( "%1 as %2 in %3" ).arg( layerProperty.geometryColName ).arg( QgsPostgresConn::displayStringForWkbType( wkbType ) ).arg( layerProperty.srids[0] );
378347

379348
QgsLayerItem::LayerType layerType;
380349
switch ( wkbType )
@@ -398,15 +367,11 @@ void QgsPGSchemaItem::addLayer( QgsPostgresLayerProperty layerProperty )
398367
layerType = QgsLayerItem::Polygon;
399368
break;
400369
default:
401-
if ( layerProperty.type.isEmpty() && layerProperty.geometryColName.isEmpty() )
402-
{
403-
layerType = QgsLayerItem::TableLayer;
404-
tip = tr( "as geometryless table" );
405-
}
406-
else
407-
{
370+
if ( !layerProperty.geometryColName.isEmpty() )
408371
return;
409-
}
372+
373+
layerType = QgsLayerItem::TableLayer;
374+
tip = tr( "as geometryless table" );
410375
}
411376

412377
QgsPGLayerItem *layerItem = new QgsPGLayerItem( this, layerProperty.tableName, mPath + "/" + layerProperty.tableName, layerType, layerProperty );
@@ -467,3 +432,10 @@ void QgsPGRootItem::newConnection()
467432
refresh();
468433
}
469434
}
435+
436+
QMainWindow *QgsPGRootItem::sMainWindow = 0;
437+
438+
QGISEXTERN void registerGui( QMainWindow *mainWindow )
439+
{
440+
QgsPGRootItem::sMainWindow = mainWindow;
441+
}

‎src/providers/postgres/qgspostgresdataitems.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#ifndef QGSPOSTGRESDATAITEMS_H
1616
#define QGSPOSTGRESDATAITEMS_H
1717

18+
#include <QMainWindow>
19+
1820
#include "qgsdataitem.h"
1921

2022
#include "qgspostgresconn.h"
@@ -40,6 +42,8 @@ class QgsPGRootItem : public QgsDataCollectionItem
4042

4143
virtual QList<QAction*> actions();
4244

45+
static QMainWindow *sMainWindow;
46+
4347
public slots:
4448
void connectionsChanged();
4549
void newConnection();
@@ -59,8 +63,6 @@ class QgsPGConnectionItem : public QgsDataCollectionItem
5963
virtual bool acceptDrop() { return true; }
6064
virtual bool handleDrop( const QMimeData * data, Qt::DropAction action );
6165

62-
QgsPostgresConn *connection() const { return mConn; }
63-
6466
void refresh();
6567

6668
signals:
@@ -69,9 +71,13 @@ class QgsPGConnectionItem : public QgsDataCollectionItem
6971
public slots:
7072
void editConnection();
7173
void deleteConnection();
74+
void refreshConnection();
7275

7376
void setLayerType( QgsPostgresLayerProperty layerProperty );
7477

78+
void threadStarted();
79+
void threadFinished();
80+
7581
private:
7682
void stop();
7783
QgsPostgresConn *mConn;

‎src/providers/postgres/qgspostgresprovider.cpp

+8-11
Original file line numberDiff line numberDiff line change
@@ -2666,12 +2666,9 @@ bool QgsPostgresProvider::getGeometryDetails()
26662666

26672667
mConnectionRO->retrieveLayerTypes( layerProperty, mUseEstimatedMetadata );
26682668

2669-
QStringList typeList = layerProperty.type.split( ",", QString::SkipEmptyParts );
2670-
QStringList sridList = layerProperty.srid.split( ",", QString::SkipEmptyParts );
2671-
Q_ASSERT( typeList.size() == sridList.size() );
26722669
mSpatialColType = layerProperty.geometryColType;
26732670

2674-
if ( typeList.size() == 0 )
2671+
if ( layerProperty.size() == 0 )
26752672
{
26762673
// no data - so take what's requested
26772674
if ( mRequestedGeomType == QGis::WKBUnknown || mRequestedSrid.isEmpty() )
@@ -2685,23 +2682,23 @@ bool QgsPostgresProvider::getGeometryDetails()
26852682
else
26862683
{
26872684
int i;
2688-
for ( i = 0; i < typeList.size(); i++ )
2685+
for ( i = 0; i < layerProperty.size(); i++ )
26892686
{
2690-
QGis::WkbType wkbType = QgsPostgresConn::wkbTypeFromPostgis( typeList.at( i ) );
2687+
QGis::WkbType wkbType = layerProperty.types[ i ];
26912688

26922689
if (( wkbType != QGis::WKBUnknown && ( mRequestedGeomType == QGis::WKBUnknown || mRequestedGeomType == wkbType ) ) &&
2693-
( mRequestedSrid.isEmpty() || sridList.at( i ) == mRequestedSrid ) )
2690+
( mRequestedSrid.isEmpty() || layerProperty.srids[ i ] == mRequestedSrid.toInt() ) )
26942691
break;
26952692
}
26962693

26972694
// requested type && srid is available
2698-
if ( i < typeList.size() )
2695+
if ( i < layerProperty.size() )
26992696
{
2700-
if ( typeList.size() == 1 )
2697+
if ( layerProperty.size() == 1 )
27012698
{
27022699
// only what we requested is available
2703-
detectedType = typeList.at( 0 );
2704-
detectedSrid = sridList.at( 0 );
2700+
detectedType = layerProperty.types[ 0 ];
2701+
detectedSrid = layerProperty.srids[ 0 ];
27052702
}
27062703
else
27072704
{

0 commit comments

Comments
 (0)
Please sign in to comment.