Skip to content

Commit 585e581

Browse files
committed
Merge MS SQL provider support. Funded by Digital Mapping Solutions (Australia) completed by Tamas Szekeres
Also includes initial drag and drop support for PostGIS
2 parents 51ece3c + f2f65d1 commit 585e581

27 files changed

+5482
-1
lines changed

CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,9 @@ IF (SPATIALITE_FOUND)
191191
SET (HAVE_SPATIALITE TRUE)
192192
ENDIF (SPATIALITE_FOUND)
193193

194+
# following variable is used in qgsconfig.h
195+
SET (HAVE_MSSQL TRUE)
196+
194197
#############################################################
195198
# search for Qt4
196199
SET(QT_MIN_VERSION 4.4.0)

cmake_templates/qgsconfig.h.in

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131

3232
#cmakedefine HAVE_SPATIALITE
3333

34+
#cmakedefine HAVE_MSSQL
35+
3436
#cmakedefine HAVE_PYTHON
3537

3638
#endif

doc/CONTRIBUTORS

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ Richard Kostecky
4949
Robert Szczepanek
5050
Stefanie Tellex
5151
Steven Mizuno
52+
Tamas Szekeres
5253
Tom Russo
5354
Tyler Mitchell
5455
Vita Cizek

images/images.qrc

+2
Original file line numberDiff line numberDiff line change
@@ -363,8 +363,10 @@
363363
<file>themes/gis/mIconSpatialite.png</file>
364364
<file>themes/gis/mIconRaster.png</file>
365365
<file>themes/gis/mIconPostgis.png</file>
366+
<file>themes/gis/mIconMssql.png</file>
366367
<file>themes/gis/mIconConnect.png</file>
367368
<file>themes/gis/mIconDbSchema.png</file>
369+
<file>themes/default/mActionAddMssqlLayer.png</file>
368370
</qresource>
369371
<qresource prefix="/images/tips">
370372
<file alias="symbol_levels.png">qgis_tips/symbol_levels.png</file>
4.12 KB
Loading

images/themes/gis/mIconMssql.png

3.24 KB
Loading

src/app/qgisapp.cpp

+34
Original file line numberDiff line numberDiff line change
@@ -860,6 +860,7 @@ void QgisApp::createActions()
860860
connect( mActionAddRasterLayer, SIGNAL( triggered() ), this, SLOT( addRasterLayer() ) );
861861
connect( mActionAddPgLayer, SIGNAL( triggered() ), this, SLOT( addDatabaseLayer() ) );
862862
connect( mActionAddSpatiaLiteLayer, SIGNAL( triggered() ), this, SLOT( addSpatiaLiteLayer() ) );
863+
connect( mActionAddMssqlLayer, SIGNAL( triggered() ), this, SLOT( addMssqlLayer() ) );
863864
connect( mActionAddWmsLayer, SIGNAL( triggered() ), this, SLOT( addWmsLayer() ) );
864865
connect( mActionAddWfsLayer, SIGNAL( triggered() ), this, SLOT( addWfsLayer() ) );
865866
connect( mActionOpenTable, SIGNAL( triggered() ), this, SLOT( attributeTable() ) );
@@ -950,6 +951,11 @@ void QgisApp::createActions()
950951
mActionAddPgLayer = NULL;
951952
#endif
952953

954+
#ifndef HAVE_MSSQL
955+
delete mActionAddMssqlLayer;
956+
mActionAddMssqlLayer = NULL;
957+
#endif
958+
953959
}
954960

955961
#include "qgsstylev2.h"
@@ -1471,6 +1477,9 @@ void QgisApp::setTheme( QString theThemeName )
14711477
#ifdef HAVE_SPATIALITE
14721478
mActionNewSpatialiteLayer->setIcon( getThemeIcon( "/mActionNewVectorLayer.png" ) );
14731479
mActionAddSpatiaLiteLayer->setIcon( getThemeIcon( "/mActionAddSpatiaLiteLayer.png" ) );
1480+
#endif
1481+
#ifdef HAVE_MSSQL
1482+
mActionAddMssqlLayer->setIcon( getThemeIcon( "/mActionAddMssqlLayer.png" ) );
14741483
#endif
14751484
mActionRemoveLayer->setIcon( getThemeIcon( "/mActionRemoveLayer.png" ) );
14761485
mActionSetLayerCRS->setIcon( getThemeIcon( "/mActionSetLayerCRS.png" ) );
@@ -2515,6 +2524,31 @@ void QgisApp::addSpatiaLiteLayer()
25152524
} // QgisApp::addSpatiaLiteLayer()
25162525
#endif
25172526

2527+
#ifndef HAVE_MSSQL
2528+
void QgisApp::addMssqlLayer() {}
2529+
#else
2530+
void QgisApp::addMssqlLayer()
2531+
{
2532+
if ( mMapCanvas && mMapCanvas->isDrawing() )
2533+
{
2534+
return;
2535+
}
2536+
2537+
// show the MS SQL dialog
2538+
QDialog *dbs = dynamic_cast<QDialog*>( QgsProviderRegistry::instance()->selectWidget( QString( "mssql" ), this ) );
2539+
if ( !dbs )
2540+
{
2541+
QMessageBox::warning( this, tr( "MSSQL" ), tr( "Cannot get MS SQL select dialog from provider." ) );
2542+
return;
2543+
}
2544+
connect( dbs , SIGNAL( addDatabaseLayers( QStringList const &, QString const & ) ),
2545+
this , SLOT( addDatabaseLayers( QStringList const &, QString const & ) ) );
2546+
dbs->exec();
2547+
delete dbs;
2548+
2549+
} // QgisApp::addMssqlLayer()
2550+
#endif
2551+
25182552
void QgisApp::addWmsLayer()
25192553
{
25202554
if ( mMapCanvas && mMapCanvas->isDrawing() )

src/app/qgisapp.h

+4
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,10 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
502502
//! Add a SpatiaLite layer to the map
503503
void addSpatiaLiteLayer();
504504
//#endif
505+
//#ifdef HAVE_MSSQL
506+
//! Add a SpatiaLite layer to the map
507+
void addMssqlLayer();
508+
//#endif
505509
/** toggles whether the current selected layer is in overview or not */
506510
void isInOverview();
507511
//! Slot to show the map coordinate position of the mouse cursor

src/gui/qgsmanageconnectionsdialog.cpp

+149
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ void QgsManageConnectionsDialog::doExportImport()
108108
case PostGIS:
109109
doc = savePgConnections( items );
110110
break;
111+
case MSSQL:
112+
doc = saveMssqlConnections( items );
113+
break;
111114
}
112115

113116
QFile file( mFileName );
@@ -161,6 +164,9 @@ void QgsManageConnectionsDialog::doExportImport()
161164
case PostGIS:
162165
loadPgConnections( doc, items );
163166
break;
167+
case MSSQL:
168+
loadMssqlConnections( doc, items );
169+
break;
164170
}
165171
// clear connections list and close window
166172
listConnections->clear();
@@ -187,6 +193,9 @@ bool QgsManageConnectionsDialog::populateConnections()
187193
case PostGIS:
188194
settings.beginGroup( "/PostgreSQL/connections" );
189195
break;
196+
case MSSQL:
197+
settings.beginGroup( "/MSSQL/connections" );
198+
break;
190199
}
191200
QStringList keys = settings.childGroups();
192201
QStringList::Iterator it = keys.begin();
@@ -256,6 +265,15 @@ bool QgsManageConnectionsDialog::populateConnections()
256265
return false;
257266
}
258267
break;
268+
269+
case MSSQL:
270+
if ( root.tagName() != "qgsMssqlConnections" )
271+
{
272+
QMessageBox::information( this, tr( "Loading connections" ),
273+
tr( "The file is not an MSSQL connections exchange file." ) );
274+
return false;
275+
}
276+
break;
259277
}
260278

261279
QDomElement child = root.firstChildElement();
@@ -363,6 +381,47 @@ QDomDocument QgsManageConnectionsDialog::savePgConnections( const QStringList &c
363381
return doc;
364382
}
365383

384+
QDomDocument QgsManageConnectionsDialog::saveMssqlConnections( const QStringList &connections )
385+
{
386+
QDomDocument doc( "connections" );
387+
QDomElement root = doc.createElement( "qgsMssqlConnections" );
388+
root.setAttribute( "version", "1.0" );
389+
doc.appendChild( root );
390+
391+
QSettings settings;
392+
QString path;
393+
for ( int i = 0; i < connections.count(); ++i )
394+
{
395+
path = "/MSSQL/connections/" + connections[ i ];
396+
QDomElement el = doc.createElement( "mssql" );
397+
el.setAttribute( "name", connections[ i ] );
398+
el.setAttribute( "host", settings.value( path + "/host", "" ).toString() );
399+
el.setAttribute( "port", settings.value( path + "/port", "" ).toString() );
400+
el.setAttribute( "database", settings.value( path + "/database", "" ).toString() );
401+
el.setAttribute( "service", settings.value( path + "/service", "" ).toString() );
402+
el.setAttribute( "sslmode", settings.value( path + "/sslmode", "1" ).toString() );
403+
el.setAttribute( "estimatedMetadata", settings.value( path + "/estimatedMetadata", "0" ).toString() );
404+
405+
el.setAttribute( "saveUsername", settings.value( path + "/saveUsername", "false" ).toString() );
406+
407+
if ( settings.value( path + "/saveUsername", "false" ).toString() == "true" )
408+
{
409+
el.setAttribute( "username", settings.value( path + "/username", "" ).toString() );
410+
}
411+
412+
el.setAttribute( "savePassword", settings.value( path + "/savePassword", "false" ).toString() );
413+
414+
if ( settings.value( path + "/savePassword", "false" ).toString() == "true" )
415+
{
416+
el.setAttribute( "password", settings.value( path + "/password", "" ).toString() );
417+
}
418+
419+
root.appendChild( el );
420+
}
421+
422+
return doc;
423+
}
424+
366425
void QgsManageConnectionsDialog::loadWMSConnections( const QDomDocument &doc, const QStringList &items )
367426
{
368427
QDomElement root = doc.documentElement();
@@ -616,6 +675,96 @@ void QgsManageConnectionsDialog::loadPgConnections( const QDomDocument &doc, con
616675
}
617676
}
618677

678+
void QgsManageConnectionsDialog::loadMssqlConnections( const QDomDocument &doc, const QStringList &items )
679+
{
680+
QDomElement root = doc.documentElement();
681+
if ( root.tagName() != "qgsMssqlConnections" )
682+
{
683+
QMessageBox::information( this,
684+
tr( "Loading connections" ),
685+
tr( "The file is not an PostGIS connections exchange file." ) );
686+
return;
687+
}
688+
689+
QString connectionName;
690+
QSettings settings;
691+
settings.beginGroup( "/MSSQL/connections" );
692+
QStringList keys = settings.childGroups();
693+
settings.endGroup();
694+
QDomElement child = root.firstChildElement();
695+
bool prompt = true;
696+
bool overwrite = true;
697+
698+
while ( !child.isNull() )
699+
{
700+
connectionName = child.attribute( "name" );
701+
if ( !items.contains( connectionName ) )
702+
{
703+
child = child.nextSiblingElement();
704+
continue;
705+
}
706+
707+
// check for duplicates
708+
if ( keys.contains( connectionName ) && prompt )
709+
{
710+
int res = QMessageBox::warning( this,
711+
tr( "Loading connections" ),
712+
tr( "Connection with name '%1' already exists. Overwrite?" )
713+
.arg( connectionName ),
714+
QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No | QMessageBox::NoToAll | QMessageBox::Cancel );
715+
switch ( res )
716+
{
717+
case QMessageBox::Cancel:
718+
return;
719+
case QMessageBox::No:
720+
child = child.nextSiblingElement();
721+
continue;
722+
case QMessageBox::Yes:
723+
overwrite = true;
724+
break;
725+
case QMessageBox::YesToAll:
726+
prompt = false;
727+
overwrite = true;
728+
break;
729+
case QMessageBox::NoToAll:
730+
prompt = false;
731+
overwrite = false;
732+
break;
733+
}
734+
}
735+
736+
if ( keys.contains( connectionName ) && !overwrite )
737+
{
738+
child = child.nextSiblingElement();
739+
continue;
740+
}
741+
742+
//no dups detected or overwrite is allowed
743+
settings.beginGroup( "/MSSQL/connections/" + connectionName );
744+
745+
settings.setValue( "/host", child.attribute( "host" ) );
746+
settings.setValue( "/port", child.attribute( "port" ) );
747+
settings.setValue( "/database", child.attribute( "database" ) );
748+
if ( child.hasAttribute( "service" ) )
749+
{
750+
settings.setValue( "/service", child.attribute( "service" ) );
751+
}
752+
else
753+
{
754+
settings.setValue( "/service", "" );
755+
}
756+
settings.setValue( "/sslmode", child.attribute( "sslmode" ) );
757+
settings.setValue( "/estimatedMetadata", child.attribute( "estimatedMetadata" ) );
758+
settings.setValue( "/saveUsername", child.attribute( "saveUsername" ) );
759+
settings.setValue( "/username", child.attribute( "username" ) );
760+
settings.setValue( "/savePassword", child.attribute( "savePassword" ) );
761+
settings.setValue( "/password", child.attribute( "password" ) );
762+
settings.endGroup();
763+
764+
child = child.nextSiblingElement();
765+
}
766+
}
767+
619768
void QgsManageConnectionsDialog::selectAll()
620769
{
621770
listConnections->selectAll();

src/gui/qgsmanageconnectionsdialog.h

+3
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class GUI_EXPORT QgsManageConnectionsDialog : public QDialog, private Ui::QgsMan
3838
WMS,
3939
PostGIS,
4040
WFS,
41+
MSSQL,
4142
};
4243

4344
// constructor
@@ -55,9 +56,11 @@ class GUI_EXPORT QgsManageConnectionsDialog : public QDialog, private Ui::QgsMan
5556
QDomDocument saveWMSConnections( const QStringList &connections );
5657
QDomDocument saveWFSConnections( const QStringList &connections );
5758
QDomDocument savePgConnections( const QStringList & connections );
59+
QDomDocument saveMssqlConnections( const QStringList & connections );
5860
void loadWMSConnections( const QDomDocument &doc, const QStringList &items );
5961
void loadWFSConnections( const QDomDocument &doc, const QStringList &items );
6062
void loadPgConnections( const QDomDocument &doc, const QStringList &items );
63+
void loadMssqlConnections( const QDomDocument &doc, const QStringList &items );
6164

6265
QString mFileName;
6366
Mode mDialogMode;

src/providers/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ ADD_SUBDIRECTORY(delimitedtext)
99
ADD_SUBDIRECTORY(osm)
1010
ADD_SUBDIRECTORY(sqlanywhere)
1111
ADD_SUBDIRECTORY(gdal)
12+
ADD_SUBDIRECTORY(mssql)
1213

1314
IF (POSTGRES_FOUND)
1415
ADD_SUBDIRECTORY(postgres)

src/providers/mssql/CMakeLists.txt

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
2+
SET (MSSQL_SRCS qgsmssqlprovider.cpp qgsmssqlgeometryparser.cpp qgsmssqlsourceselect.cpp qgsmssqltablemodel.cpp qgsmssqlnewconnection.cpp qgsmssqldataitems.cpp)
3+
4+
SET (MSSQL_MOC_HDRS qgsmssqlprovider.h qgsmssqlsourceselect.h qgsmssqltablemodel.h qgsmssqlnewconnection.h qgsmssqldataitems.h)
5+
6+
########################################################
7+
# Build
8+
9+
QT4_WRAP_CPP(MSSQL_MOC_SRCS ${MSSQL_MOC_HDRS})
10+
11+
INCLUDE_DIRECTORIES(
12+
.
13+
../../core
14+
${GDAL_INCLUDE_DIR}
15+
${GEOS_INCLUDE_DIR}
16+
${QT_INCLUDE_DIR}
17+
../../gui
18+
${CMAKE_CURRENT_BINARY_DIR}/../../ui
19+
)
20+
21+
22+
ADD_LIBRARY(mssqlprovider MODULE ${MSSQL_SRCS} ${MSSQL_MOC_SRCS})
23+
24+
TARGET_LINK_LIBRARIES(mssqlprovider
25+
qgis_core
26+
qgis_gui
27+
${QT_QTSQL_LIBRARY}
28+
)
29+
########################################################
30+
# Install
31+
32+
INSTALL (TARGETS mssqlprovider
33+
RUNTIME DESTINATION ${QGIS_PLUGIN_DIR}
34+
LIBRARY DESTINATION ${QGIS_PLUGIN_DIR})
35+

0 commit comments

Comments
 (0)