Skip to content

Commit d047ea0

Browse files
committedMar 26, 2014
Merge remote-tracking branch 'tamas/master'
2 parents 20933de + 1911232 commit d047ea0

File tree

6 files changed

+321
-136
lines changed

6 files changed

+321
-136
lines changed
 

‎src/providers/mssql/qgsmssqlfeatureiterator.cpp

Lines changed: 156 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -23,53 +23,44 @@
2323
#include <QTextStream>
2424

2525

26-
QgsMssqlFeatureIterator::QgsMssqlFeatureIterator( QgsMssqlProvider* provider, const QgsFeatureRequest& request )
27-
: QgsAbstractFeatureIterator( request ), mProvider( provider )
26+
QgsMssqlFeatureIterator::QgsMssqlFeatureIterator( QgsMssqlFeatureSource* source, bool ownSource, const QgsFeatureRequest& request )
27+
: QgsAbstractFeatureIteratorFromSource( source, ownSource, request )
2828
{
29-
mIsOpen = false;
30-
BuildStatement( request );
31-
29+
mClosed = false;
3230
mQuery = NULL;
3331

34-
if ( mProvider->mQuery.isActive() )
35-
{
36-
mUseProviderQuery = false;
37-
// create a separate database connection if the default query is active
38-
QgsDebugMsg( "Creating a separate database connection" );
39-
QString id;
40-
// QString::sprintf adds 0x prefix
41-
id.sprintf( "%p", this );
42-
mDatabase = mProvider->mDatabase.cloneDatabase( mProvider->mDatabase, id );
43-
if ( !mDatabase.open() )
44-
{
45-
QgsDebugMsg( "Failed to open database" );
46-
QString msg = mDatabase.lastError().text();
47-
QgsDebugMsg( msg );
48-
return;
49-
}
50-
// create sql query
51-
mQuery = new QSqlQuery( mDatabase );
52-
}
53-
else
32+
mParser.IsGeography = mSource->mIsGeography;
33+
34+
BuildStatement( request );
35+
36+
// connect to the database
37+
mDatabase = GetDatabase(mSource->mDriver, mSource->mHost, mSource->mDatabaseName, mSource->mUserName, mSource->mPassword);
38+
39+
if ( !mDatabase.open() )
5440
{
55-
mUseProviderQuery = true;
56-
mQuery = &mProvider->mQuery;
41+
QgsDebugMsg( "Failed to open database" );
42+
QString msg = mDatabase.lastError().text();
43+
QgsDebugMsg( msg );
44+
return;
5745
}
46+
47+
// create sql query
48+
mQuery = new QSqlQuery( mDatabase );
49+
5850
// start selection
5951
rewind();
6052
}
6153

6254

6355
QgsMssqlFeatureIterator::~QgsMssqlFeatureIterator()
6456
{
65-
if ( !mUseProviderQuery )
66-
{
67-
if ( mQuery )
57+
close();
58+
59+
if ( mQuery )
6860
delete mQuery;
61+
62+
if (mDatabase.isOpen())
6963
mDatabase.close();
70-
}
71-
else if ( mIsOpen )
72-
close();
7364
}
7465

7566
void QgsMssqlFeatureIterator::BuildStatement( const QgsFeatureRequest& request )
@@ -87,9 +78,9 @@ void QgsMssqlFeatureIterator::BuildStatement( const QgsFeatureRequest& request )
8778
{
8879
if ( fieldCount != 0 )
8980
mStatement += ",";
90-
mStatement += "[" + mProvider->mAttributeFields[*it].name() + "]";
81+
mStatement += "[" + mSource->mFields[*it].name() + "]";
9182

92-
if ( !mProvider->mFidColName.isEmpty() && mProvider->mFidColName == mProvider->mAttributeFields[*it].name() )
83+
if ( !mSource->mFidColName.isEmpty() && mSource->mFidColName == mSource->mFields[*it].name() )
9384
mFidCol = fieldCount;
9485

9586
++fieldCount;
@@ -99,43 +90,43 @@ void QgsMssqlFeatureIterator::BuildStatement( const QgsFeatureRequest& request )
9990
else
10091
{
10192
// get all attributes
102-
for ( int i = 0; i < mProvider->mAttributeFields.count(); i++ )
93+
for ( int i = 0; i < mSource->mFields.count(); i++ )
10394
{
10495
if ( fieldCount != 0 )
10596
mStatement += ",";
106-
mStatement += "[" + mProvider->mAttributeFields[i].name() + "]";
97+
mStatement += "[" + mSource->mFields[i].name() + "]";
10798

108-
if ( !mProvider->mFidColName.isEmpty() && mProvider->mFidColName == mProvider->mAttributeFields[i].name() )
99+
if ( !mSource->mFidColName.isEmpty() && mSource->mFidColName == mSource->mFields[i].name() )
109100
mFidCol = fieldCount;
110101

111102
++fieldCount;
112103
mAttributesToFetch.append( i );
113104
}
114105
}
115106
// get fid col if not yet required
116-
if ( mFidCol == -1 && !mProvider->mFidColName.isEmpty() )
107+
if ( mFidCol == -1 && !mSource->mFidColName.isEmpty() )
117108
{
118109
if ( fieldCount != 0 )
119110
mStatement += ",";
120-
mStatement += "[" + mProvider->mFidColName + "]";
111+
mStatement += "[" + mSource->mFidColName + "]";
121112
mFidCol = fieldCount;
122113
++fieldCount;
123114
}
124115
// get geometry col
125-
if ( !( request.flags() & QgsFeatureRequest::NoGeometry ) && !mProvider->mGeometryColName.isEmpty() )
116+
if ( !( request.flags() & QgsFeatureRequest::NoGeometry ) && !mSource->mGeometryColName.isEmpty() )
126117
{
127118
if ( fieldCount != 0 )
128119
mStatement += ",";
129-
mStatement += "[" + mProvider->mGeometryColName + "]";
120+
mStatement += "[" + mSource->mGeometryColName + "]";
130121
mGeometryCol = fieldCount;
131122
++fieldCount;
132123
}
133124

134125
mStatement += " from ";
135-
if ( !mProvider->mSchemaName.isEmpty() )
136-
mStatement += "[" + mProvider->mSchemaName + "].";
126+
if ( !mSource->mSchemaName.isEmpty() )
127+
mStatement += "[" + mSource->mSchemaName + "].";
137128

138-
mStatement += "[" + mProvider->mTableName + "]";
129+
mStatement += "[" + mSource->mTableName + "]";
139130

140131
bool filterAdded = false;
141132
// set spatial filter
@@ -154,27 +145,27 @@ void QgsMssqlFeatureIterator::BuildStatement( const QgsFeatureRequest& request )
154145
<< request.filterRect().xMinimum() << " " << request.filterRect().yMinimum();
155146

156147
mStatement += QString( " where [%1].STIntersects([%2]::STGeomFromText('POLYGON((%3))',%4)) = 1" ).arg(
157-
mProvider->mGeometryColName, mProvider->mGeometryColType, r, QString::number( mProvider->mSRId ) );
148+
mSource->mGeometryColName, mSource->mGeometryColType, r, QString::number( mSource->mSRId ) );
158149
filterAdded = true;
159150
}
160151

161152
// set fid filter
162-
if (( request.filterType() & QgsFeatureRequest::FilterFid ) && !mProvider->mFidColName.isEmpty() )
153+
if (( request.filterType() & QgsFeatureRequest::FilterFid ) && !mSource->mFidColName.isEmpty() )
163154
{
164155
// set attribute filter
165156
if ( !filterAdded )
166-
mStatement += QString( " where [%1] = %2" ).arg( mProvider->mFidColName, QString::number( request.filterFid() ) );
157+
mStatement += QString( " where [%1] = %2" ).arg( mSource->mFidColName, QString::number( request.filterFid() ) );
167158
else
168-
mStatement += QString( " and [%1] = %2" ).arg( mProvider->mFidColName, QString::number( request.filterFid() ) );
159+
mStatement += QString( " and [%1] = %2" ).arg( mSource->mFidColName, QString::number( request.filterFid() ) );
169160
filterAdded = true;
170161
}
171162

172-
if ( !mProvider->mSqlWhereClause.isEmpty() )
163+
if ( !mSource->mSqlWhereClause.isEmpty() )
173164
{
174165
if ( !filterAdded )
175-
mStatement += " where (" + mProvider->mSqlWhereClause + ")";
166+
mStatement += " where (" + mSource->mSqlWhereClause + ")";
176167
else
177-
mStatement += " and (" + mProvider->mSqlWhereClause + ")";
168+
mStatement += " and (" + mSource->mSqlWhereClause + ")";
178169
}
179170

180171
if ( fieldCount == 0 )
@@ -200,8 +191,8 @@ bool QgsMssqlFeatureIterator::fetchFeature( QgsFeature& feature )
200191

201192
if ( mQuery->next() )
202193
{
203-
feature.initAttributes( mProvider->mAttributeFields.count() );
204-
feature.setFields( &mProvider->mAttributeFields ); // allow name-based attribute lookups
194+
feature.initAttributes( mSource->mFields.count() );
195+
feature.setFields( &mSource->mFields ); // allow name-based attribute lookups
205196

206197
for ( int i = 0; i < mAttributesToFetch.count(); i++ )
207198
{
@@ -217,10 +208,10 @@ bool QgsMssqlFeatureIterator::fetchFeature( QgsFeature& feature )
217208
if ( mGeometryCol >= 0 )
218209
{
219210
QByteArray ar = mQuery->value( mGeometryCol ).toByteArray();
220-
unsigned char* wkb = mProvider->parser.ParseSqlGeometry(( unsigned char* )ar.data(), ar.size() );
211+
unsigned char* wkb = mParser.ParseSqlGeometry(( unsigned char* )ar.data(), ar.size() );
221212
if ( wkb )
222213
{
223-
feature.setGeometryAndOwnership( wkb, mProvider->parser.GetWkbLen() );
214+
feature.setGeometryAndOwnership( wkb, mParser.GetWkbLen() );
224215
}
225216
}
226217

@@ -249,27 +240,128 @@ bool QgsMssqlFeatureIterator::rewind()
249240
QString msg = mQuery->lastError().text();
250241
QgsDebugMsg( msg );
251242
}
252-
else
253-
mIsOpen = true;
254243

255244
return true;
256245
}
257246

258247
bool QgsMssqlFeatureIterator::close()
259248
{
260-
mIsOpen = false;
261-
if ( !mQuery )
249+
if ( mClosed )
262250
return false;
263251

264-
if ( !mQuery->isActive() )
252+
if ( mQuery )
265253
{
266-
QgsDebugMsg( "QgsMssqlFeatureIterator::close on inactive query" );
267-
return false;
254+
if ( !mQuery->isActive() )
255+
{
256+
QgsDebugMsg( "QgsMssqlFeatureIterator::close on inactive query" );
257+
return false;
258+
}
259+
260+
mQuery->finish();
268261
}
269262

270-
mQuery->finish();
263+
iteratorClosed();
264+
265+
mClosed = true;
271266
return true;
272267
}
273268

269+
QSqlDatabase QgsMssqlFeatureIterator::GetDatabase(QString driver, QString host, QString database, QString username, QString password)
270+
{
271+
QSqlDatabase db;
272+
QString connectionName;
273+
274+
// create a separate database connection for each feature source
275+
QgsDebugMsg( "Creating a separate database connection" );
276+
QString id;
277+
278+
// QString::sprintf adds 0x prefix
279+
id.sprintf( "%p", this );
280+
281+
if ( driver.isEmpty() )
282+
{
283+
if ( host.isEmpty() )
284+
{
285+
QgsDebugMsg( "QgsMssqlProvider host name not specified" );
286+
return db;
287+
}
288+
289+
if ( database.isEmpty() )
290+
{
291+
QgsDebugMsg( "QgsMssqlProvider database name not specified" );
292+
return db;
293+
}
294+
connectionName = host + "." + database + "." + id;
295+
}
296+
else
297+
connectionName = driver;
298+
299+
if ( !QSqlDatabase::contains( connectionName ) )
300+
db = QSqlDatabase::addDatabase( "QODBC", connectionName );
301+
else
302+
db = QSqlDatabase::database( connectionName );
303+
304+
db.setHostName( host );
305+
QString connectionString = "";
306+
if ( !driver.isEmpty() )
307+
{
308+
// driver was specified explicitly
309+
connectionString = driver;
310+
}
311+
else
312+
{
313+
#ifdef WIN32
314+
connectionString = "driver={SQL Server}";
315+
#else
316+
connectionString = "driver={FreeTDS};port=1433";
317+
#endif
318+
}
319+
320+
if ( !host.isEmpty() )
321+
connectionString += ";server=" + host;
322+
323+
if ( !database.isEmpty() )
324+
connectionString += ";database=" + database;
325+
326+
if ( password.isEmpty() )
327+
connectionString += ";trusted_connection=yes";
328+
else
329+
connectionString += ";uid=" + username + ";pwd=" + password;
330+
331+
if ( !username.isEmpty() )
332+
db.setUserName( username );
333+
334+
if ( !password.isEmpty() )
335+
db.setPassword( password );
336+
337+
db.setDatabaseName( connectionString );
338+
return db;
339+
}
340+
274341
///////////////
275342

343+
QgsMssqlFeatureSource::QgsMssqlFeatureSource( const QgsMssqlProvider* p )
344+
: mFields( p->mAttributeFields )
345+
, mFidColName( p->mFidColName )
346+
, mGeometryColName( p->mGeometryColName )
347+
, mGeometryColType( p->mGeometryColType )
348+
, mUserName( p->mUserName )
349+
, mService( p->mService )
350+
, mDatabaseName( p->mDatabaseName )
351+
, mHost( p->mHost )
352+
, mSchemaName( p->mSchemaName )
353+
, mTableName( p->mTableName )
354+
, mSqlWhereClause( p->mSqlWhereClause )
355+
{
356+
mSRId = p->mSRId;
357+
mIsGeography = p->mParser.IsGeography;
358+
}
359+
360+
QgsMssqlFeatureSource::~QgsMssqlFeatureSource()
361+
{
362+
}
363+
364+
QgsFeatureIterator QgsMssqlFeatureSource::getFeatures( const QgsFeatureRequest& request )
365+
{
366+
return QgsFeatureIterator( new QgsMssqlFeatureIterator( this, false, request ) );
367+
}

‎src/providers/mssql/qgsmssqlfeatureiterator.h

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,57 @@
1818
#ifndef QGSMSSQLFEATUREITERATOR_H
1919
#define QGSMSSQLFEATUREITERATOR_H
2020

21-
#include "qgsmssqlprovider.h"
21+
#include "qgsmssqlgeometryparser.h"
2222
#include "qgsfeatureiterator.h"
2323
#include <QtSql/QSqlDatabase>
2424
#include <QtSql/QSqlQuery>
2525
#include <QtSql/QSqlError>
2626

2727
class QgsMssqlProvider;
2828

29-
class QgsMssqlFeatureIterator : public QgsAbstractFeatureIterator
29+
class QgsMssqlFeatureSource : public QgsAbstractFeatureSource
3030
{
3131
public:
32-
QgsMssqlFeatureIterator( QgsMssqlProvider* provider, const QgsFeatureRequest& request );
32+
QgsMssqlFeatureSource( const QgsMssqlProvider* p );
33+
~QgsMssqlFeatureSource();
34+
35+
virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest& request );
36+
37+
protected:
38+
QgsFields mFields;
39+
QString mFidColName;
40+
long mSRId;
41+
42+
/* sql geo type */
43+
bool mIsGeography;
44+
45+
QString mGeometryColName;
46+
QString mGeometryColType;
47+
48+
// current layer name
49+
QString mSchemaName;
50+
QString mTableName;
51+
52+
// login
53+
QString mUserName;
54+
QString mPassword;
55+
56+
// server access
57+
QString mService;
58+
QString mDriver;
59+
QString mDatabaseName;
60+
QString mHost;
61+
62+
// SQL statement used to limit the features retrieved
63+
QString mSqlWhereClause;
64+
65+
friend class QgsMssqlFeatureIterator;
66+
};
67+
68+
class QgsMssqlFeatureIterator : public QgsAbstractFeatureIteratorFromSource<QgsMssqlFeatureSource>
69+
{
70+
public:
71+
QgsMssqlFeatureIterator( QgsMssqlFeatureSource* source, bool ownSource, const QgsFeatureRequest& request );
3372

3473
~QgsMssqlFeatureIterator();
3574

@@ -40,10 +79,11 @@ class QgsMssqlFeatureIterator : public QgsAbstractFeatureIterator
4079
virtual bool close();
4180

4281
protected:
43-
QgsMssqlProvider* mProvider;
44-
82+
4583
void BuildStatement( const QgsFeatureRequest& request );
4684

85+
QSqlDatabase GetDatabase(QString driver, QString host, QString database, QString username, QString password);
86+
4787
private:
4888
//! fetch next feature, return true on success
4989
virtual bool fetchFeature( QgsFeature& feature );
@@ -60,9 +100,6 @@ class QgsMssqlFeatureIterator : public QgsAbstractFeatureIterator
60100
// The current sql statement
61101
QString mStatement;
62102

63-
// Open connection flag
64-
bool mIsOpen;
65-
66103
// Field index of FID column
67104
long mFidCol;
68105

@@ -71,6 +108,9 @@ class QgsMssqlFeatureIterator : public QgsAbstractFeatureIterator
71108

72109
// List of attribute indices to fetch with nextFeature calls
73110
QgsAttributeList mAttributesToFetch;
111+
112+
// for parsing sql geometries
113+
QgsMssqlGeometryParser mParser;
74114
};
75115

76116
#endif // QGSMSSQLFEATUREITERATOR_H

‎src/providers/mssql/qgsmssqlgeometryparser.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* *
1616
***************************************************************************/
1717

18-
#include "qgsmssqlprovider.h"
18+
#include "qgsmssqlgeometryparser.h"
1919
#include "qgsgeometry.h"
2020
#include "qgslogger.h"
2121
#include "qgsapplication.h"
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/***************************************************************************
2+
qgsmssqlgeometryparser.h - description
3+
-------------------
4+
begin : 2014-03-16
5+
copyright : (C) 2014 by Tamas Szekeres
6+
email : szekerest at gmail.com
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
18+
#ifndef QGSMSSQLGEOMETRYPARSER_H
19+
#define QGSMSSQLGEOMETRYPARSER_H
20+
21+
22+
/**
23+
\class QgsMssqlGeometryParser
24+
\brief Geometry parser for SqlGeometry/SqlGeography.
25+
*
26+
*/
27+
28+
class QgsMssqlGeometryParser
29+
{
30+
31+
protected:
32+
unsigned char* pszData;
33+
unsigned char* pszWkb;
34+
int nWkbLen;
35+
int nWkbMaxLen;
36+
/* byte order */
37+
char chByteOrder;
38+
/* serialization properties */
39+
char chProps;
40+
/* point array */
41+
int nPointSize;
42+
int nPointPos;
43+
int nNumPoints;
44+
/* figure array */
45+
int nFigurePos;
46+
int nNumFigures;
47+
/* shape array */
48+
int nShapePos;
49+
int nNumShapes;
50+
int nSRSId;
51+
52+
protected:
53+
void CopyBytes( void* src, int len );
54+
void CopyCoordinates( int iPoint );
55+
void CopyPoint( int iPoint );
56+
void ReadPoint( int iShape );
57+
void ReadMultiPoint( int iShape );
58+
void ReadLineString( int iShape );
59+
void ReadMultiLineString( int iShape );
60+
void ReadPolygon( int iShape );
61+
void ReadMultiPolygon( int iShape );
62+
void ReadGeometryCollection( int iShape );
63+
64+
public:
65+
QgsMssqlGeometryParser();
66+
unsigned char* ParseSqlGeometry( unsigned char* pszInput, int nLen );
67+
int GetSRSId() { return nSRSId; };
68+
int GetWkbLen() { return nWkbLen; };
69+
void DumpMemoryToLog( const char* pszMsg, unsigned char* pszInput, int nLen );
70+
/* sql geo type */
71+
bool IsGeography;
72+
};
73+
74+
75+
#endif // QGSMSSQLGEOMETRYPARSER_H

‎src/providers/mssql/qgsmssqlprovider.cpp

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,17 @@ QgsMssqlProvider::QgsMssqlProvider( QString uri )
7171
mUseWkb = false;
7272
mSkipFailures = false;
7373

74+
mUserName = anUri.username();
75+
mPassword = anUri.password();
76+
mService = anUri.service();
77+
mDatabaseName = anUri.database();
78+
mHost = anUri.host();
79+
7480
mUseEstimatedMetadata = anUri.useEstimatedMetadata();
7581

7682
mSqlWhereClause = anUri.sql();
7783

78-
mDatabase = GetDatabase( anUri.service(), anUri.host(), anUri.database(), anUri.username(), anUri.password() );
84+
mDatabase = QgsMssqlProvider::GetDatabase(mDriver, mHost, mDatabaseName, mUserName, mPassword);
7985

8086
if ( !OpenDatabase( mDatabase ) )
8187
{
@@ -161,6 +167,13 @@ QgsMssqlProvider::QgsMssqlProvider( QString uri )
161167

162168
QgsMssqlProvider::~QgsMssqlProvider()
163169
{
170+
if (mDatabase.isOpen())
171+
mDatabase.close();
172+
}
173+
174+
QgsAbstractFeatureSource* QgsMssqlProvider::featureSource() const
175+
{
176+
return new QgsMssqlFeatureSource( this );
164177
}
165178

166179
QgsFeatureIterator QgsMssqlProvider::getFeatures( const QgsFeatureRequest& request )
@@ -171,7 +184,7 @@ QgsFeatureIterator QgsMssqlProvider::getFeatures( const QgsFeatureRequest& reque
171184
return QgsFeatureIterator();
172185
}
173186

174-
return QgsFeatureIterator( new QgsMssqlFeatureIterator( this, request ) );
187+
return QgsFeatureIterator( new QgsMssqlFeatureIterator( new QgsMssqlFeatureSource( this ), true, request ) );
175188
}
176189

177190
bool QgsMssqlProvider::OpenDatabase( QSqlDatabase db )
@@ -186,10 +199,14 @@ bool QgsMssqlProvider::OpenDatabase( QSqlDatabase db )
186199
return true;
187200
}
188201

189-
QSqlDatabase QgsMssqlProvider::GetDatabase( QString driver, QString host, QString database, QString username, QString password )
202+
QSqlDatabase QgsMssqlProvider::GetDatabase(QString driver, QString host, QString database, QString username, QString password)
190203
{
191204
QSqlDatabase db;
192205
QString connectionName;
206+
207+
// create a separate database connection for each feature source
208+
QgsDebugMsg( "Creating a separate database connection" );
209+
193210
if ( driver.isEmpty() )
194211
{
195212
if ( host.isEmpty() )
@@ -353,7 +370,7 @@ void QgsMssqlProvider::loadFields()
353370
{
354371
mGeometryColName = query.value( 3 ).toString();
355372
mGeometryColType = sqlTypeName;
356-
parser.IsGeography = sqlTypeName == "geography";
373+
mParser.IsGeography = sqlTypeName == "geography";
357374
}
358375
else
359376
{
@@ -649,10 +666,10 @@ void QgsMssqlProvider::UpdateStatistics( bool estimate )
649666
while ( query.next() )
650667
{
651668
QByteArray ar = query.value( 0 ).toByteArray();
652-
unsigned char* wkb = parser.ParseSqlGeometry(( unsigned char* )ar.data(), ar.size() );
669+
unsigned char* wkb = mParser.ParseSqlGeometry(( unsigned char* )ar.data(), ar.size() );
653670
if ( wkb )
654671
{
655-
geom.fromWkb( wkb, parser.GetWkbLen() );
672+
geom.fromWkb( wkb, mParser.GetWkbLen() );
656673
QgsRectangle rect = geom.boundingBox();
657674

658675
if ( rect.xMinimum() < mExtent.xMinimum() )
@@ -665,7 +682,7 @@ void QgsMssqlProvider::UpdateStatistics( bool estimate )
665682
mExtent.setYMaximum( rect.yMaximum() );
666683

667684
mWkbType = geom.wkbType();
668-
mSRId = parser.GetSRSId();
685+
mSRId = mParser.GetSRSId();
669686
}
670687
}
671688
}

‎src/providers/mssql/qgsmssqlprovider.h

Lines changed: 17 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -37,60 +37,7 @@ class QgsMssqlFeatureIterator;
3737

3838
#include "qgsdatasourceuri.h"
3939
#include "qgsgeometry.h"
40-
41-
42-
/**
43-
\class QgsMssqlGeometryParser
44-
\brief Geometry parser for SqlGeometry/SqlGeography.
45-
*
46-
*/
47-
48-
class QgsMssqlGeometryParser
49-
{
50-
51-
protected:
52-
unsigned char* pszData;
53-
unsigned char* pszWkb;
54-
int nWkbLen;
55-
int nWkbMaxLen;
56-
/* byte order */
57-
char chByteOrder;
58-
/* serialization properties */
59-
char chProps;
60-
/* point array */
61-
int nPointSize;
62-
int nPointPos;
63-
int nNumPoints;
64-
/* figure array */
65-
int nFigurePos;
66-
int nNumFigures;
67-
/* shape array */
68-
int nShapePos;
69-
int nNumShapes;
70-
int nSRSId;
71-
72-
protected:
73-
void CopyBytes( void* src, int len );
74-
void CopyCoordinates( int iPoint );
75-
void CopyPoint( int iPoint );
76-
void ReadPoint( int iShape );
77-
void ReadMultiPoint( int iShape );
78-
void ReadLineString( int iShape );
79-
void ReadMultiLineString( int iShape );
80-
void ReadPolygon( int iShape );
81-
void ReadMultiPolygon( int iShape );
82-
void ReadGeometryCollection( int iShape );
83-
84-
public:
85-
QgsMssqlGeometryParser();
86-
unsigned char* ParseSqlGeometry( unsigned char* pszInput, int nLen );
87-
int GetSRSId() { return nSRSId; };
88-
int GetWkbLen() { return nWkbLen; };
89-
void DumpMemoryToLog( const char* pszMsg, unsigned char* pszInput, int nLen );
90-
/* sql geo type */
91-
bool IsGeography;
92-
};
93-
40+
#include "qgsmssqlgeometryparser.h"
9441

9542
/**
9643
\class QgsMssqlProvider
@@ -108,6 +55,9 @@ class QgsMssqlProvider : public QgsVectorDataProvider
10855
virtual ~QgsMssqlProvider();
10956

11057
static QSqlDatabase GetDatabase( QString driver, QString host, QString database, QString username, QString password );
58+
59+
virtual QgsAbstractFeatureSource* featureSource() const;
60+
11161
static bool OpenDatabase( QSqlDatabase db );
11262

11363
/* Implementation of functions from QgsVectorDataProvider */
@@ -304,7 +254,7 @@ class QgsMssqlProvider : public QgsVectorDataProvider
304254
QgsFields mAttributeFields;
305255
QMap<int, QVariant> mDefaultValues;
306256

307-
QgsMssqlGeometryParser parser;
257+
QgsMssqlGeometryParser mParser;
308258

309259
//! Layer extent
310260
QgsRectangle mExtent;
@@ -343,6 +293,17 @@ class QgsMssqlProvider : public QgsVectorDataProvider
343293
// current layer name
344294
QString mSchemaName;
345295
QString mTableName;
296+
297+
// login
298+
QString mUserName;
299+
QString mPassword;
300+
301+
// server access
302+
QString mService;
303+
QString mDriver;
304+
QString mDatabaseName;
305+
QString mHost;
306+
346307
// available tables
347308
QStringList mTables;
348309

@@ -358,7 +319,7 @@ class QgsMssqlProvider : public QgsVectorDataProvider
358319
static void mssqlWkbTypeAndDimension( QGis::WkbType wkbType, QString &geometryType, int &dim );
359320
static QGis::WkbType getWkbType( QString geometryType, int dim );
360321

361-
friend class QgsMssqlFeatureIterator;
322+
friend class QgsMssqlFeatureSource;
362323
};
363324

364325
#endif // QGSMSSQLPROVIDER_H

0 commit comments

Comments
 (0)
Please sign in to comment.