Skip to content

Commit d212ca7

Browse files
committed
Adding the native MSSQL provider
1 parent a2ee769 commit d212ca7

25 files changed

+5411
-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)