/
qgsmssqlprovider.h
348 lines (275 loc) · 10.4 KB
/
qgsmssqlprovider.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
/***************************************************************************
qgsmssqlprovider.h - Data provider for mssql server
-------------------
begin : 2011-10-08
copyright : (C) 2011 by Tamas Szekeres
email : szekerest at gmail.com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsvectordataprovider.h"
#include "qgscoordinatereferencesystem.h"
#include "qgsvectorlayerimport.h"
#include <QStringList>
#include <QFile>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlQuery>
#include <QtSql/QSqlError>
class QgsFeature;
class QgsField;
class QFile;
class QTextStream;
#include "qgsdatasourceuri.h"
#include "qgsgeometry.h"
/**
\class QgsMssqlGeometryParser
\brief Geometry parser for SqlGeometry/SqlGeography.
*
*/
class QgsMssqlGeometryParser
{
protected:
unsigned char* pszData;
unsigned char* pszWkb;
int nWkbLen;
int nWkbMaxLen;
/* byte order */
char chByteOrder;
/* serialization properties */
char chProps;
/* point array */
int nPointSize;
int nPointPos;
int nNumPoints;
/* figure array */
int nFigurePos;
int nNumFigures;
/* shape array */
int nShapePos;
int nNumShapes;
int nSRSId;
protected:
void CopyBytes( void* src, int len );
void CopyPoint( int iPoint );
void ReadPoint( int iShape );
void ReadMultiPoint( int iShape );
void ReadLineString( int iShape );
void ReadMultiLineString( int iShape );
void ReadPolygon( int iShape );
void ReadMultiPolygon( int iShape );
void ReadGeometryCollection( int iShape );
public:
QgsMssqlGeometryParser();
unsigned char* ParseSqlGeometry( unsigned char* pszInput, int nLen );
int GetSRSId() { return nSRSId; };
int GetWkbLen() { return nWkbLen; };
void DumpMemoryToLog( const char* pszMsg, unsigned char* pszInput, int nLen );
};
/**
\class QgsMssqlProvider
\brief Data provider for mssql server.
*
*/
class QgsMssqlProvider : public QgsVectorDataProvider
{
Q_OBJECT
public:
QgsMssqlProvider( QString uri = QString() );
virtual ~QgsMssqlProvider();
static QSqlDatabase GetDatabase( QString driver, QString host, QString database, QString username, QString password );
static bool OpenDatabase( QSqlDatabase db );
/* Implementation of functions from QgsVectorDataProvider */
/**
* Returns the permanent storage type for this layer as a friendly name.
*/
virtual QString storageType() const;
/**
* Sub-layers handled by this provider, in order from bottom to top
*
* Sub-layers are used when the provider's source can combine layers
* it knows about in some way before it hands them off to the provider.
*/
virtual QStringList subLayers() const;
/** Select features based on a bounding rectangle. Features can be retrieved with calls to nextFeature.
* @param fetchAttributes list of attributes which should be fetched
* @param rect spatial filter
* @param fetchGeometry true if the feature geometry should be fetched
* @param useIntersect true if an accurate intersection test should be used,
* false if a test based on bounding box is sufficient
*/
virtual void select( QgsAttributeList fetchAttributes = QgsAttributeList(),
QgsRectangle rect = QgsRectangle(),
bool fetchGeometry = true,
bool useIntersect = false );
/**
* Get the next feature resulting from a select operation.
* @param feature feature which will receive data from the provider
* @return true when there was a feature to fetch, false when end was hit
*
* mFile should be open with the file pointer at the record of the next
* feature, or EOF. The feature found on the current line is parsed.
*/
virtual bool nextFeature( QgsFeature& feature );
/**
* Gets the feature at the given feature ID.
* @param featureId id of the feature
* @param feature feature which will receive the data
* @param fetchGeoemtry if true, geometry will be fetched from the provider
* @param fetchAttributes a list containing the indexes of the attribute fields to copy
* @return True when feature was found, otherwise false
*/
virtual bool featureAtId( QgsFeatureId featureId,
QgsFeature& feature,
bool fetchGeometry = true,
QgsAttributeList fetchAttributes = QgsAttributeList() );
/**
* Get feature type.
* @return int representing the feature type
*/
virtual QGis::WkbType geometryType() const;
/**
* Number of features in the layer
* @return long containing number of features
*/
virtual long featureCount() const;
/**
* Number of attribute fields for a feature in the layer
*/
virtual uint fieldCount() const;
/** update the extent, feature count, wkb type and srid for this layer */
void UpdateStatistics();
/**
* Return a map of indexes with field names for this layer
* @return map of fields
*/
virtual const QgsFieldMap & fields() const;
/** Restart reading features from previous select operation */
virtual void rewind();
/** Returns a bitmask containing the supported capabilities
Note, some capabilities may change depending on whether
a spatial filter is active on this provider, so it may
be prudent to check this value per intended operation.
*/
virtual int capabilities() const;
/* Implementation of functions from QgsDataProvider */
/** return a provider name
Essentially just returns the provider key. Should be used to build file
dialogs so that providers can be shown with their supported types. Thus
if more than one provider supports a given format, the user is able to
select a specific provider to open that file.
@note
Instead of being pure virtual, might be better to generalize this
behavior and presume that none of the sub-classes are going to do
anything strange with regards to their name or description?
*/
QString name() const;
/** return description
Return a terse string describing what the provider is.
@note
Instead of being pure virtual, might be better to generalize this
behavior and presume that none of the sub-classes are going to do
anything strange with regards to their name or description?
*/
QString description() const;
/**
* Return the extent for this data layer
*/
virtual QgsRectangle extent();
/**
* Returns true if this is a valid data source
*/
bool isValid();
/**Writes a list of features to the database*/
virtual bool addFeatures( QgsFeatureList & flist );
/**Deletes a feature*/
virtual bool deleteFeatures( const QgsFeatureIds & id );
/**
* Adds new attributes
* @param attributes list of new attributes
* @return true in case of success and false in case of failure
* @note added in 1.2
*/
virtual bool addAttributes( const QList<QgsField> &attributes );
/**
* Deletes existing attributes
* @param attributes a set containing names of attributes
* @return true in case of success and false in case of failure
*/
virtual bool deleteAttributes( const QgsAttributeIds &attributes );
/**Changes attribute values of existing features */
virtual bool changeAttributeValues( const QgsChangedAttributesMap & attr_map );
/**Changes existing geometries*/
virtual bool changeGeometryValues( QgsGeometryMap & geometry_map );
/**
* Create a spatial index for the current layer
*/
virtual bool createSpatialIndex();
/**Create an attribute index on the datasource*/
virtual bool createAttributeIndex( int field );
/** convert a QgsField to work with MSSQL */
static bool convertField( QgsField &field );
/** Import a vector layer into the database */
static QgsVectorLayerImport::ImportError createEmptyLayer(
const QString& uri,
const QgsFieldMap &fields,
QGis::WkbType wkbType,
const QgsCoordinateReferenceSystem *srs,
bool overwrite,
QMap<int, int> *oldToNewAttrIdxMap,
QString *errorMessage = 0,
const QMap<QString, QVariant> *options = 0
);
virtual QgsCoordinateReferenceSystem crs();
protected:
/** loads fields from input file to member attributeFields */
QVariant::Type DecodeODBCType( int sqltype );
void loadFields();
void loadMetadata();
private:
//! Fields
QgsFieldMap mAttributeFields;
QgsMssqlGeometryParser parser;
int mFieldCount; // Note: this includes field count for wkt field
//! Layer extent
QgsRectangle mExtent;
bool mValid;
bool mUseWkb;
bool mSkipFailures;
int mGeomType;
long mNumberFeatures;
long mFidCol;
QString mFidColName;
long mSRId;
long mGeometryCol;
QString mGeometryColName;
QString mGeometryColType;
// QString containing the last reported error message
QString mLastError;
// Coordinate reference sytem
QgsCoordinateReferenceSystem mCrs;
QGis::WkbType mWkbType;
// The database object
QSqlDatabase mDatabase;
// The current sql query
QSqlQuery mQuery;
// The current sql statement
QString mStatement;
// current layer name
QString mSchemaName;
QString mTableName;
// available tables
QStringList mTables;
// Sets the error messages
void setLastError( QString error )
{
mLastError = error;
}
static void mssqlWkbTypeAndDimension( QGis::WkbType wkbType, QString &geometryType, int &dim );
static QGis::WkbType getWkbType( QString geometryType, int dim );
};