121 changes: 51 additions & 70 deletions src/providers/oracle/qgsoracledataitems.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "qgslogger.h"
#include "qgsdatasourceuri.h"
#include "qgsapplication.h"
#include "qgsmessageoutput.h"

#include <QMessageBox>
#include <QProgressDialog>
Expand Down Expand Up @@ -78,73 +79,38 @@ void QgsOracleConnectionItem::refresh()
QVector<QgsDataItem*> QgsOracleConnectionItem::createChildren()
{
QgsDebugMsg( "Entered" );
QVector<QgsDataItem*> children;
QgsDataSourceURI uri = QgsOracleConn::connUri( mName );

mOwnerMap.clear();

mConn = QgsOracleConn::connectDb( uri.connectionInfo() );
if ( !mConn )
return children;

QVector<QgsOracleLayerProperty> layerProperties;
if ( !mConn->supportedLayers( layerProperties,
QgsOracleConn::userTablesOnly( mName ),
QgsOracleConn::allowGeometrylessTables( mName ) ) )
{
children.append( new QgsErrorItem( this, tr( "Failed to retrieve layers" ), mPath + "/error" ) );
return children;
}

if ( layerProperties.isEmpty() )
{
children.append( new QgsErrorItem( this, tr( "No layers found." ), mPath + "/error" ) );
return children;
}

stop();

foreach ( QgsOracleLayerProperty layerProperty, layerProperties )
if ( !mColumnTypeThread )
{
QgsOracleOwnerItem *ownerItem = mOwnerMap.value( layerProperty.ownerName, 0 );
if ( !ownerItem )
{
ownerItem = new QgsOracleOwnerItem( this, layerProperty.ownerName, mPath + "/" + layerProperty.ownerName );
children.append( ownerItem );
mOwnerMap[ layerProperty.ownerName ] = ownerItem;
}
mColumnTypeThread = new QgsOracleColumnTypeThread( mName, true /* useEstimatedMetadata */ );

if ( !layerProperty.geometryColName.isNull() )
{
if ( layerProperty.types.contains( QGis::WKBUnknown ) || layerProperty.srids.isEmpty() )
{
if ( !mColumnTypeThread )
{
QgsOracleConn *conn = QgsOracleConn::connectDb( uri.connectionInfo() );
if ( conn )
{
mColumnTypeThread = new QgsOracleColumnTypeThread( conn, true /* use estimated metadata */ );

connect( mColumnTypeThread, SIGNAL( setLayerType( QgsOracleLayerProperty ) ),
this, SLOT( setLayerType( QgsOracleLayerProperty ) ) );
connect( this, SIGNAL( addGeometryColumn( QgsOracleLayerProperty ) ),
mColumnTypeThread, SLOT( addGeometryColumn( QgsOracleLayerProperty ) ) );
}
}

emit addGeometryColumn( layerProperty );
}
}
else
{
ownerItem->addLayer( layerProperty );
}
connect( mColumnTypeThread, SIGNAL( setLayerType( QgsOracleLayerProperty ) ),
this, SLOT( setLayerType( QgsOracleLayerProperty ) ) );
connect( mColumnTypeThread, SIGNAL( started() ), this, SLOT( threadStarted() ) );
connect( mColumnTypeThread, SIGNAL( finished() ), this, SLOT( threadFinished() ) );
}

if ( mColumnTypeThread )
mColumnTypeThread->start();

return children;
return QVector<QgsDataItem*>();
}

void QgsOracleConnectionItem::threadStarted()
{
QgsDebugMsg( "Entering." );
qApp->setOverrideCursor( Qt::BusyCursor );
}

void QgsOracleConnectionItem::threadFinished()
{
QgsDebugMsg( "Entering." );
qApp->restoreOverrideCursor();
}

void QgsOracleConnectionItem::setLayerType( QgsOracleLayerProperty layerProperty )
Expand All @@ -154,21 +120,26 @@ void QgsOracleConnectionItem::setLayerType( QgsOracleLayerProperty layerProperty
QgsOracleOwnerItem *ownerItem = mOwnerMap.value( layerProperty.ownerName, 0 );
if ( !ownerItem )
{
QgsDebugMsg( QString( "owner item for %1 not found." ).arg( layerProperty.ownerName ) );
return;
ownerItem = new QgsOracleOwnerItem( this, layerProperty.ownerName, mPath + "/" + layerProperty.ownerName );
QgsDebugMsg( "add owner item: " + layerProperty.ownerName );
addChildItem( ownerItem, true );
mOwnerMap[ layerProperty.ownerName ] = ownerItem;
}

for ( int i = 0 ; i < layerProperty.size(); i++ )
{
QGis::WkbType wkbType = layerProperty.types.at( i );
if ( wkbType == QGis::WKBUnknown )
{
// skip any geometry entry
QgsDebugMsg( "skip unknown geometry type" );
continue;
}

QgsDebugMsg( "ADD LAYER" );
ownerItem->addLayer( layerProperty.at( i ) );
}

QgsDebugMsg( "Leaving" );
}

bool QgsOracleConnectionItem::equal( const QgsDataItem *other )
Expand All @@ -179,7 +150,7 @@ bool QgsOracleConnectionItem::equal( const QgsDataItem *other )
}

const QgsOracleConnectionItem *o = qobject_cast<const QgsOracleConnectionItem *>( other );
return ( mPath == o->mPath && mName == o->mName && o->connection() == connection() );
return ( mPath == o->mPath && mName == o->mName && o->parent() == parent() );
}

QList<QAction*> QgsOracleConnectionItem::actions()
Expand All @@ -194,6 +165,10 @@ QList<QAction*> QgsOracleConnectionItem::actions()
connect( actionDelete, SIGNAL( triggered() ), this, SLOT( deleteConnection() ) );
lst.append( actionDelete );

QAction* actionRefresh = new QAction( tr( "Refresh" ), this );
connect( actionRefresh, SIGNAL( triggered() ), this, SLOT( refreshConnection() ) );
lst.append( actionRefresh );

return lst;
}

Expand All @@ -215,6 +190,12 @@ void QgsOracleConnectionItem::deleteConnection()
mParent->refresh();
}

void QgsOracleConnectionItem::refreshConnection()
{
// the parent should be updated
refresh();
}

bool QgsOracleConnectionItem::handleDrop( const QMimeData * data, Qt::DropAction )
{
if ( !QgsMimeDataUtils::isUriList( data ) )
Expand Down Expand Up @@ -250,7 +231,7 @@ bool QgsOracleConnectionItem::handleDrop( const QMimeData * data, Qt::DropAction
uri.setDataSource( QString(), u.name.left( 30 ).toUpper(), "QGS_GEOMETRY" );
uri.setWkbType( srcLayer->wkbType() );
QString authid = srcLayer->crs().authid();
if( authid.startsWith( "EPSG:", Qt::CaseInsensitive ) )
if ( authid.startsWith( "EPSG:", Qt::CaseInsensitive ) )
{
uri.setSrid( authid.mid( 5 ) );
}
Expand Down Expand Up @@ -281,15 +262,17 @@ bool QgsOracleConnectionItem::handleDrop( const QMimeData * data, Qt::DropAction

if ( hasError )
{
QMessageBox::warning( 0, tr( "Import to Oracle database" ), tr( "Failed to import some layers!\n\n" ) + importResults.join( "\n" ) );
QgsMessageOutput *output = QgsMessageOutput::createMessageOutput();
output->setTitle( tr( "Import to Oracle database" ) );
output->setMessage( tr( "Failed to import some layers!\n\n" ) + importResults.join( "\n" ), QgsMessageOutput::MessageText );
output->showMessage();
}
else
{
QMessageBox::information( 0, tr( "Import to Oracle database" ), tr( "Import was successful." ) );
refresh();
}

refresh();

return true;
}

Expand Down Expand Up @@ -328,29 +311,27 @@ void QgsOracleLayerItem::deleteLayer()
else
{
QMessageBox::information( 0, tr( "Delete layer" ), tr( "Layer deleted successfully." ) );
mParent->refresh();
deleteLater();
}
}

QString QgsOracleLayerItem::createUri()
{
QString pkColName = mLayerProperty.pkCols.size() > 0 ? mLayerProperty.pkCols.at( 0 ) : QString::null;
Q_ASSERT( mLayerProperty.size() == 1 );

QgsOracleConnectionItem *connItem = qobject_cast<QgsOracleConnectionItem *>( parent() ? parent()->parent() : 0 );

if ( !connItem )
{
QgsDebugMsg( "connection item not found." );
return QString::null;
}

QgsDebugMsg( QString( "connInfo: %1" ).arg( connItem->connection()->connInfo() ) );

QgsDataSourceURI uri( connItem->connection()->connInfo() );
QgsDataSourceURI uri = QgsOracleConn::connUri( connItem->name() );
uri.setDataSource( mLayerProperty.ownerName, mLayerProperty.tableName, mLayerProperty.geometryColName, mLayerProperty.sql, QString::null );
Q_ASSERT( mLayerProperty.size() == 1 );
uri.setSrid( QString::number( mLayerProperty.srids.at( 0 ) ) );
uri.setWkbType( mLayerProperty.types.at( 0 ) );
if ( mLayerProperty.isView && mLayerProperty.pkCols.size() > 0 )
uri.setKeyColumn( mLayerProperty.pkCols[0] );
QgsDebugMsg( QString( "layer uri: %1" ).arg( uri.uri() ) );
return uri.uri();
}
Expand Down Expand Up @@ -415,7 +396,7 @@ void QgsOracleOwnerItem::addLayer( QgsOracleLayerProperty layerProperty )

QgsOracleLayerItem *layerItem = new QgsOracleLayerItem( this, layerProperty.tableName, mPath + "/" + layerProperty.tableName, layerType, layerProperty );
layerItem->setToolTip( tip );
addChild( layerItem );
addChildItem( layerItem, true );
}

// ---------------------------------------------------------------------------
Expand Down
7 changes: 4 additions & 3 deletions src/providers/oracle/qgsoracledataitems.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@ class QgsOracleConnectionItem : public QgsDataCollectionItem
virtual bool acceptDrop() { return true; }
virtual bool handleDrop( const QMimeData * data, Qt::DropAction action );

QgsOracleConn *connection() const { return mConn; }

void refresh();

signals:
Expand All @@ -73,12 +71,15 @@ class QgsOracleConnectionItem : public QgsDataCollectionItem
public slots:
void editConnection();
void deleteConnection();
void refreshConnection();

void setLayerType( QgsOracleLayerProperty layerProperty );

void threadStarted();
void threadFinished();

private:
void stop();
QgsOracleConn *mConn;
QMap<QString, QgsOracleOwnerItem * > mOwnerMap;
QgsOracleColumnTypeThread *mColumnTypeThread;
};
Expand Down
263 changes: 188 additions & 75 deletions src/providers/oracle/qgsoracleprovider.cpp

Large diffs are not rendered by default.

15 changes: 13 additions & 2 deletions src/providers/oracle/qgsoracleprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -381,8 +381,19 @@ class QgsOracleProvider : public QgsVectorDataProvider

struct OracleException
{
OracleException( const QSqlQuery &q )
: mWhat( tr( "Oracle-Error: %1\nSQL: %2\n" ).arg( q.lastError().text() ).arg( q.lastQuery() ) )
OracleException( QString msg, const QSqlQuery &q )
: mWhat( tr( "Oracle error: %1\nSQL: %2\nError: %3" )
.arg( msg )
.arg( q.lastError().text() )
.arg( q.lastQuery() )
)
{}

OracleException( QString msg, const QSqlDatabase &q )
: mWhat( tr( "Oracle error: %1\nError: %2" )
.arg( msg )
.arg( q.lastError().text() )
)
{}

OracleException( const OracleException &e )
Expand Down
94 changes: 10 additions & 84 deletions src/providers/oracle/qgsoraclesourceselect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -462,71 +462,20 @@ void QgsOracleSourceSelect::on_btnConnect_clicked()
mConnInfo = uri.connectionInfo();
mUseEstimatedMetadata = uri.useEstimatedMetadata();

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

mIsConnected = true;
mTablesTreeDelegate->setConn( QgsOracleConn::connectDb( uri.connectionInfo() ) );

bool userTablesOnly = QgsOracleConn::userTablesOnly( cmbConnections->currentText() );
bool allowGeometrylessTables = cbxAllowGeometrylessTables->isChecked();
QApplication::setOverrideCursor( Qt::BusyCursor );

QVector<QgsOracleLayerProperty> layers;
if ( conn->supportedLayers( layers, userTablesOnly, allowGeometrylessTables ) )
{
// Add the supported layers to the table
foreach ( QgsOracleLayerProperty layer, layers )
{
if ( !layer.geometryColName.isNull() )
{
if ( layer.types.contains( QGis::WKBUnknown ) || layer.srids.isEmpty() )
{
addSearchGeometryColumn( layer );
}
}
else
{
QgsDebugMsg( QString( "adding table %1.%2" ).arg( layer.ownerName ).arg( layer.tableName ) );
layer.types.clear();
layer.srids.clear();
mTableModel.addTableEntry( layer );
}
}

if ( mColumnTypeThread )
{
btnConnect->setText( tr( "Stop" ) );
mColumnTypeThread->start();
}
}
mIsConnected = true;
mTablesTreeDelegate->setConn( QgsOracleConn::connectDb( uri.connectionInfo() ) );

//if we have only one owner 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 QgsOracleColumnTypeThread( cmbConnections->currentText(), mUseEstimatedMetadata );

conn->disconnect();
connect( mColumnTypeThread, SIGNAL( setLayerType( QgsOracleLayerProperty ) ),
this, SLOT( setLayerType( QgsOracleLayerProperty ) ) );
connect( mColumnTypeThread, SIGNAL( finished() ),
this, SLOT( columnThreadFinished() ) );

if ( !mColumnTypeThread )
{
finishList();
}
}
else
{
// Let user know we couldn't initialise the Oracle provider
QMessageBox::warning( this,
tr( "Oracle Locator Provider" ),
tr( "Could not open the Oracle Locator Provider" ) );
}
btnConnect->setText( tr( "Stop" ) );
mColumnTypeThread->start();
}

void QgsOracleSourceSelect::finishList()
Expand Down Expand Up @@ -601,29 +550,6 @@ void QgsOracleSourceSelect::setSql( const QModelIndex &index )
delete vlayer;
}

void QgsOracleSourceSelect::addSearchGeometryColumn( QgsOracleLayerProperty layerProperty )
{
// store the column details and do the query in a thread
if ( !mColumnTypeThread )
{
QgsOracleConn *conn = QgsOracleConn::connectDb( mConnInfo );
if ( conn )
{

mColumnTypeThread = new QgsOracleColumnTypeThread( conn, mUseEstimatedMetadata );

connect( mColumnTypeThread, SIGNAL( setLayerType( QgsOracleLayerProperty ) ),
this, SLOT( setLayerType( QgsOracleLayerProperty ) ) );
connect( this, SIGNAL( addGeometryColumn( QgsOracleLayerProperty ) ),
mColumnTypeThread, SLOT( addGeometryColumn( QgsOracleLayerProperty ) ) );
connect( mColumnTypeThread, SIGNAL( finished() ),
this, SLOT( columnThreadFinished() ) );
}
}

emit addGeometryColumn( layerProperty );
}

QString QgsOracleSourceSelect::fullDescription( QString owner, QString table, QString column, QString type )
{
QString full_desc = "";
Expand Down
1 change: 0 additions & 1 deletion src/providers/oracle/qgsoraclesourceselect.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ class QgsOracleSourceSelect : public QDialog, private Ui::QgsDbSourceSelectBase
signals:
void addDatabaseLayers( QStringList const & layerPathList, QString const & providerKey );
void connectionsChanged();
void addGeometryColumn( QgsOracleLayerProperty );

public slots:
//! Determines the tables the user selected and closes the dialog
Expand Down
9 changes: 6 additions & 3 deletions src/providers/postgres/qgspostgresdataitems.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "qgslogger.h"
#include "qgsdatasourceuri.h"
#include "qgsapplication.h"
#include "qgsmessageoutput.h"

#include <QMessageBox>

Expand Down Expand Up @@ -229,15 +230,17 @@ bool QgsPGConnectionItem::handleDrop( const QMimeData * data, Qt::DropAction )

if ( hasError )
{
QMessageBox::warning( 0, tr( "Import to PostGIS database" ), tr( "Failed to import some layers!\n\n" ) + importResults.join( "\n" ) );
QgsMessageOutput *output = QgsMessageOutput::createMessageOutput();
output->setTitle( tr( "Import to PostGIS database" ) );
output->setMessage( tr( "Failed to import some layers!\n\n" ) + importResults.join( "\n" ), QgsMessageOutput::MessageText );
output->showMessage();
}
else
{
QMessageBox::information( 0, tr( "Import to PostGIS database" ), tr( "Import was successful." ) );
refresh();
}

refresh();

return true;
}

Expand Down
9 changes: 6 additions & 3 deletions src/providers/spatialite/qgsspatialitedataitems.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "qgslogger.h"
#include "qgsmimedatautils.h"
#include "qgsvectorlayerimport.h"
#include "qgsmessageoutput.h"

#include <QAction>
#include <QMessageBox>
Expand Down Expand Up @@ -226,15 +227,17 @@ bool QgsSLConnectionItem::handleDrop( const QMimeData * data, Qt::DropAction )

if ( hasError )
{
QMessageBox::warning( 0, tr( "Import to SpatiaLite database" ), tr( "Failed to import some layers!\n\n" ) + importResults.join( "\n" ) );
QgsMessageOutput *output = QgsMessageOutput::createMessageOutput();
output->setTitle( tr( "Import to SpatiaLite database" ) );
output->setMessage( tr( "Failed to import some layers!\n\n" ) + importResults.join( "\n" ), QgsMessageOutput::MessageText );
output->showMessage();
}
else
{
QMessageBox::information( 0, tr( "Import to SpatiaLite database" ), tr( "Import was successful." ) );
refresh();
}

refresh();

return true;
}

Expand Down