Skip to content

Commit

Permalink
postgres provider:
Browse files Browse the repository at this point in the history
- move available table detection to thread
- more progress messages
  • Loading branch information
jef-n committed May 12, 2013
1 parent 4182baa commit b85af12
Show file tree
Hide file tree
Showing 10 changed files with 357 additions and 453 deletions.
56 changes: 45 additions & 11 deletions src/providers/postgres/qgscolumntypethread.cpp
Expand Up @@ -16,22 +16,20 @@ email : jef at norbit dot de
***************************************************************************/

#include "qgscolumntypethread.h"
#include "qgslogger.h"

#include <QMetaType>

QgsGeomColumnTypeThread::QgsGeomColumnTypeThread( QgsPostgresConn *conn, bool useEstimatedMetaData )
QgsGeomColumnTypeThread::QgsGeomColumnTypeThread( QString name, bool useEstimatedMetaData, bool allowGeometrylessTables )
: QThread()
, mConn( conn )
, mConn( 0 )
, mName( name )
, mUseEstimatedMetadata( useEstimatedMetaData )
, mAllowGeometrylessTables( allowGeometrylessTables )
{
qRegisterMetaType<QgsPostgresLayerProperty>( "QgsPostgresLayerProperty" );
}

void QgsGeomColumnTypeThread::addGeometryColumn( QgsPostgresLayerProperty layerProperty )
{
layerProperties << layerProperty;
}

void QgsGeomColumnTypeThread::stop()
{
if ( !mConn )
Expand All @@ -43,31 +41,67 @@ void QgsGeomColumnTypeThread::stop()

void QgsGeomColumnTypeThread::run()
{
QgsDataSourceURI uri = QgsPostgresConn::connUri( mName );
mConn = QgsPostgresConn::connectDb( uri.connectionInfo(), true );
if ( !mConn )
{
QgsDebugMsg( "Connection failed - " + uri.connectionInfo() );
return;
}

mStopped = false;

bool dontResolveType = QgsPostgresConn::dontResolveType( mName );

emit progressMessage( tr( "Retrieving tables of %1..." ).arg( mName ) );
QVector<QgsPostgresLayerProperty> layerProperties;
if ( !mConn->supportedLayers( layerProperties,
QgsPostgresConn::geometryColumnsOnly( mName ),
QgsPostgresConn::publicSchemaOnly( mName ),
mAllowGeometrylessTables ) ||
layerProperties.isEmpty() )
{
return;
}

int i = 0;
foreach ( QgsPostgresLayerProperty layerProperty, layerProperties )
{
if ( !mStopped )
{
emit progress( i++, layerProperties.size() );
emit progressMessage( tr( "Scanning column %1.%2.%3..." ).arg( layerProperty.schemaName ).arg( layerProperty.tableName ).arg( layerProperty.geometryColName ) );
mConn->retrieveLayerTypes( layerProperty, mUseEstimatedMetadata );
emit progressMessage( tr( "Scanning column %1.%2.%3..." )
.arg( layerProperty.schemaName )
.arg( layerProperty.tableName )
.arg( layerProperty.geometryColName ) );

if ( !layerProperty.geometryColName.isNull() &&
( layerProperty.types.value( 0, QGis::WKBUnknown ) == QGis::WKBUnknown ||
layerProperty.srids.value( 0, 0 ) == 0 ) )
{
if ( dontResolveType )
{
QgsDebugMsg( QString( "skipping column %1.%2 without type constraint" ).arg( layerProperty.schemaName ).arg( layerProperty.tableName ) );
continue;
}

mConn->retrieveLayerTypes( layerProperty, mUseEstimatedMetadata );
}
}

if ( mStopped )
{
layerProperty.type = "";
layerProperty.srid = "";
layerProperty.types.clear();
layerProperty.srids.clear();
}

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

emit progress( 0, 0 );
emit progressMessage( tr( "Table retrieval finished." ) );

mConn->disconnect();
mConn = 0;
}
5 changes: 3 additions & 2 deletions src/providers/postgres/qgscolumntypethread.h
Expand Up @@ -28,7 +28,7 @@ class QgsGeomColumnTypeThread : public QThread
{
Q_OBJECT
public:
QgsGeomColumnTypeThread( QgsPostgresConn *conn, bool useEstimatedMetaData );
QgsGeomColumnTypeThread( QString connName, bool useEstimatedMetaData, bool allowGeometrylessTables );

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

public slots:
void addGeometryColumn( QgsPostgresLayerProperty layerProperty );
void stop();

private:
QgsGeomColumnTypeThread() {}

QgsPostgresConn *mConn;
QString mName;
bool mUseEstimatedMetadata;
bool mAllowGeometrylessTables;
bool mStopped;
QList<QgsPostgresLayerProperty> layerProperties;
};
Expand Down
135 changes: 25 additions & 110 deletions src/providers/postgres/qgspgsourceselect.cpp
Expand Up @@ -120,14 +120,18 @@ QgsPgSourceSelect::QgsPgSourceSelect( QWidget *parent, Qt::WFlags fl, bool manag
: QDialog( parent, fl )
, mManagerMode( managerMode )
, mEmbeddedMode( embeddedMode )
, mColumnTypeThread( NULL )
, mColumnTypeThread( 0 )
{
setupUi( this );

if ( mEmbeddedMode )
{
buttonBox->button( QDialogButtonBox::Close )->hide();
}
else
{
setWindowTitle( tr( "Add PostGIS Table(s)" ) );
}

mAddButton = new QPushButton( tr( "&Add" ) );
mAddButton->setEnabled( false );
Expand Down Expand Up @@ -352,7 +356,7 @@ void QgsPgSourceSelect::on_mSearchModeComboBox_currentIndexChanged( const QStrin
void QgsPgSourceSelect::setLayerType( QgsPostgresLayerProperty layerProperty )
{
QgsDebugMsg( "entering." );
mTableModel.setGeometryTypesForTable( layerProperty );
mTableModel.addTableEntry( layerProperty );
}

QgsPgSourceSelect::~QgsPgSourceSelect()
Expand Down Expand Up @@ -437,80 +441,21 @@ void QgsPgSourceSelect::on_btnConnect_clicked()
mConnInfo = uri.connectionInfo();
mUseEstimatedMetadata = uri.useEstimatedMetadata();

QgsPostgresConn *conn = QgsPostgresConn::connectDb( uri.connectionInfo(), true );
if ( conn )
{
QApplication::setOverrideCursor( Qt::WaitCursor );

bool searchPublicOnly = QgsPostgresConn::publicSchemaOnly( cmbConnections->currentText() );
bool searchGeometryColumnsOnly = QgsPostgresConn::geometryColumnsOnly( cmbConnections->currentText() );
bool dontResolveType = QgsPostgresConn::dontResolveType( cmbConnections->currentText() );
bool allowGeometrylessTables = cbxAllowGeometrylessTables->isChecked();

emit progressMessage( tr( "Retrieving tables from %1..." ).arg( cmbConnections->currentText() ) );

QVector<QgsPostgresLayerProperty> layers;
if ( conn->supportedLayers( layers, searchGeometryColumnsOnly, searchPublicOnly, allowGeometrylessTables ) )
{
// Add the supported layers to the table
foreach ( QgsPostgresLayerProperty layer, layers )
{
QString type = layer.type;
QString srid = layer.srid;
if ( !layer.geometryColName.isNull() )
{
if ( QgsPostgresConn::wkbTypeFromPostgis( type ) == QGis::WKBUnknown || srid.isEmpty() )
{
if ( dontResolveType )
{
QgsDebugMsg( QString( "skipping column %1.%2 without type constraint" ).arg( layer.schemaName ).arg( layer.tableName ) );
continue;
}

addSearchGeometryColumn( layer );
type = "";
srid = "";
}
}
QgsDebugMsg( QString( "adding table %1.%2" ).arg( layer.schemaName ).arg( layer.tableName ) );

layer.type = type;
layer.srid = srid;
mTableModel.addTableEntry( layer );
}

if ( mColumnTypeThread )
{
btnConnect->setText( tr( "Stop" ) );
mColumnTypeThread->start();
}
}
QApplication::setOverrideCursor( Qt::BusyCursor );

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

conn->disconnect();
connect( mColumnTypeThread, SIGNAL( setLayerType( QgsPostgresLayerProperty ) ),
this, SLOT( setLayerType( QgsPostgresLayerProperty ) ) );
connect( mColumnTypeThread, SIGNAL( finished() ),
this, SLOT( columnThreadFinished() ) );
connect( mColumnTypeThread, SIGNAL( progress( int, int ) ),
this, SIGNAL( progress( int, int ) ) );
connect( mColumnTypeThread, SIGNAL( progressMessage( QString ) ),
this, SIGNAL( progressMessage( QString ) ) );

if ( !mColumnTypeThread )
{
finishList();
}
}
else
{
// Let user know we couldn't initialise the Postgres/PostGIS provider
QMessageBox::warning( this,
tr( "Postgres/PostGIS Provider" ),
tr( "Could not open the Postgres/PostGIS Provider.\nCheck message log for possible errors." ) );
}
btnConnect->setText( tr( "Stop" ) );
mColumnTypeThread->start();
}

void QgsPgSourceSelect::finishList()
Expand All @@ -527,15 +472,6 @@ void QgsPgSourceSelect::finishList()

mTablesTreeView->sortByColumn( QgsPgTableModel::dbtmTable, Qt::AscendingOrder );
mTablesTreeView->sortByColumn( QgsPgTableModel::dbtmSchema, Qt::AscendingOrder );

emit progress( 0, 0 );
emit progressMessage( tr( "Table retrieval finished." ) );

if ( mTablesTreeView->model()->rowCount() == 0 )
QMessageBox::information( this,
tr( "Postgres/PostGIS Provider" ),
tr( "No accessible tables or views found.\nCheck the message log for possible errors." ) );

}

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

QgsVectorLayer *vlayer = new QgsVectorLayer( mTableModel.layerURI( idx, mConnInfo, mUseEstimatedMetadata ), tableName, "postgres" );
QString uri = mTableModel.layerURI( idx, mConnInfo, mUseEstimatedMetadata );
if ( uri.isNull() )
{
QgsDebugMsg( "no uri" );
return;
}

QgsVectorLayer *vlayer = new QgsVectorLayer( uri, tableName, "postgres" );
if ( !vlayer->isValid() )
{
delete vlayer;
Expand All @@ -587,33 +529,6 @@ void QgsPgSourceSelect::setSql( const QModelIndex &index )
delete vlayer;
}

void QgsPgSourceSelect::addSearchGeometryColumn( QgsPostgresLayerProperty layerProperty )
{
// store the column details and do the query in a thread
if ( !mColumnTypeThread )
{
QgsPostgresConn *conn = QgsPostgresConn::connectDb( mConnInfo, true /* readonly */ );
if ( conn )
{

mColumnTypeThread = new QgsGeomColumnTypeThread( conn, mUseEstimatedMetadata );

connect( mColumnTypeThread, SIGNAL( setLayerType( QgsPostgresLayerProperty ) ),
this, SLOT( setLayerType( QgsPostgresLayerProperty ) ) );
connect( this, SIGNAL( addGeometryColumn( QgsPostgresLayerProperty ) ),
mColumnTypeThread, SLOT( addGeometryColumn( QgsPostgresLayerProperty ) ) );
connect( mColumnTypeThread, SIGNAL( finished() ),
this, SLOT( columnThreadFinished() ) );
connect( mColumnTypeThread, SIGNAL( progress( int, int ) ),
this, SIGNAL( progress( int, int ) ) );
connect( mColumnTypeThread, SIGNAL( progressMessage( QString ) ),
this, SIGNAL( progressMessage( QString ) ) );
}
}

emit addGeometryColumn( layerProperty );
}

QString QgsPgSourceSelect::fullDescription( QString schema, QString table, QString column, QString type )
{
QString full_desc = "";
Expand Down

0 comments on commit b85af12

Please sign in to comment.