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 "qgscolumntypethread.h"
#include "qgslogger.h"


#include <QMetaType> #include <QMetaType>


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


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

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


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


mStopped = false; 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; int i = 0;
foreach ( QgsPostgresLayerProperty layerProperty, layerProperties ) foreach ( QgsPostgresLayerProperty layerProperty, layerProperties )
{ {
if ( !mStopped ) if ( !mStopped )
{ {
emit progress( i++, layerProperties.size() ); emit progress( i++, layerProperties.size() );
emit progressMessage( tr( "Scanning column %1.%2.%3..." ).arg( layerProperty.schemaName ).arg( layerProperty.tableName ).arg( layerProperty.geometryColName ) ); emit progressMessage( tr( "Scanning column %1.%2.%3..." )
mConn->retrieveLayerTypes( layerProperty, mUseEstimatedMetadata ); .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 ) if ( mStopped )
{ {
layerProperty.type = ""; layerProperty.types.clear();
layerProperty.srid = ""; layerProperty.srids.clear();
} }


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


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

mConn->disconnect(); mConn->disconnect();
mConn = 0; 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 Q_OBJECT
public: public:
QgsGeomColumnTypeThread( QgsPostgresConn *conn, bool useEstimatedMetaData ); QgsGeomColumnTypeThread( QString connName, bool useEstimatedMetaData, bool allowGeometrylessTables );


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


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


private: private:
QgsGeomColumnTypeThread() {} QgsGeomColumnTypeThread() {}


QgsPostgresConn *mConn; QgsPostgresConn *mConn;
QString mName;
bool mUseEstimatedMetadata; bool mUseEstimatedMetadata;
bool mAllowGeometrylessTables;
bool mStopped; bool mStopped;
QList<QgsPostgresLayerProperty> layerProperties; 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 ) : QDialog( parent, fl )
, mManagerMode( managerMode ) , mManagerMode( managerMode )
, mEmbeddedMode( embeddedMode ) , mEmbeddedMode( embeddedMode )
, mColumnTypeThread( NULL ) , mColumnTypeThread( 0 )
{ {
setupUi( this ); setupUi( this );


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


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


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


QgsPostgresConn *conn = QgsPostgresConn::connectDb( uri.connectionInfo(), true ); QApplication::setOverrideCursor( Qt::BusyCursor );
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();
}
}


//if we have only one schema item, expand it by default mColumnTypeThread = new QgsGeomColumnTypeThread( cmbConnections->currentText(), mUseEstimatedMetadata, cbxAllowGeometrylessTables->isChecked() );
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 ) ) ) );
}
}


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 ) btnConnect->setText( tr( "Stop" ) );
{ mColumnTypeThread->start();
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." ) );
}
} }


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


mTablesTreeView->sortByColumn( QgsPgTableModel::dbtmTable, Qt::AscendingOrder ); mTablesTreeView->sortByColumn( QgsPgTableModel::dbtmTable, Qt::AscendingOrder );
mTablesTreeView->sortByColumn( QgsPgTableModel::dbtmSchema, 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() void QgsPgSourceSelect::columnThreadFinished()
Expand Down Expand Up @@ -568,8 +504,14 @@ void QgsPgSourceSelect::setSql( const QModelIndex &index )
QModelIndex idx = mProxyModel.mapToSource( index ); QModelIndex idx = mProxyModel.mapToSource( index );
QString tableName = mTableModel.itemFromIndex( idx.sibling( idx.row(), QgsPgTableModel::dbtmTable ) )->text(); 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() ) if ( !vlayer->isValid() )
{ {
delete vlayer; delete vlayer;
Expand All @@ -587,33 +529,6 @@ void QgsPgSourceSelect::setSql( const QModelIndex &index )
delete vlayer; 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 QgsPgSourceSelect::fullDescription( QString schema, QString table, QString column, QString type )
{ {
QString full_desc = ""; QString full_desc = "";
Expand Down

0 comments on commit b85af12

Please sign in to comment.