-
-
Notifications
You must be signed in to change notification settings - Fork 3k
/
qgssqlanywhereprovider.h
423 lines (367 loc) · 13.2 KB
/
qgssqlanywhereprovider.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
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
/***************************************************************************
qgssqlanywhereprovider.h - QGIS data provider for SQL Anywhere DBMS
------------------------
begin : Dec 2010
copyright : (C) 2010 by iAnywhere Solutions, Inc.
author : David DeHaan
email : ddehaan at sybase dot 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 3 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/* $Id$ */
#ifndef QGSSQLANYWHEREPROVIDER_H
#define QGSSQLANYWHEREPROVIDER_H
#include "qgsdatasourceuri.h"
#include "qgsvectordataprovider.h"
#include "qgsrectangle.h"
#include <list>
#include <queue>
#include <fstream>
#include <set>
#include <QMutex>
class QgsFeature;
class QgsField;
#include "sqlanyconnection.h"
#include "sqlanystatement.h"
/**
\class QgsSqlAnywhereProvider
\brief Data provider for SQL Anywhere layers.
This provider implements the interface defined in the QgsDataProvider
class to provide access to spatial data residing in a SQL Anywhere database.
*/
class QgsSqlAnywhereProvider: public QgsVectorDataProvider
{
Q_OBJECT
public:
/**
* Constructor of the vector provider
* @param uri uniform resource locator (URI) for a dataset
*/
QgsSqlAnywhereProvider( QString const &uri = "" );
//! Destructor
virtual ~ QgsSqlAnywhereProvider();
/**
* Returns the permanent storage type for this layer as a friendly name.
*/
virtual QString storageType() const;
/** Get the QgsCoordinateReferenceSystem for this layer */
QgsCoordinateReferenceSystem crs() { return mCrs; }
/** Gets the feature at the given feature ID
* @param featureId of feature to retrieve
* @param feature which will receive data from the provider
* @param fetchGeometry true if the feature geometry should be fetched
* @param fetchAttributes list of attributes which should be fetched
*/
virtual bool featureAtId( int featureId,
QgsFeature & feature, bool fetchGeometry = true, QgsAttributeList fetchAttributes = QgsAttributeList() );
/** Accessor for sql where clause used to limit dataset */
virtual QString subsetString();
/** mutator for sql where clause used to limit dataset size */
virtual bool setSubsetString( QString theSQL );
virtual bool supportsSubsetString() { return true; }
/** 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
*/
virtual bool nextFeature( QgsFeature & feature );
/** Get the feature type. This corresponds to
* WKBPoint,
* WKBLineString,
* WKBPolygon,
* WKBMultiPoint,
* WKBMultiLineString or
* WKBMultiPolygon
* as defined in qgis.h
*/
QGis::WkbType geometryType() const { return mGeomType; }
/**
* return the number of layers for the current data source
*/
size_t layerCount() const { return 1; }
/**
* Get the number of features in the layer
*/
long featureCount() const { return mNumberFeatures; }
/**
* Return the extent for this data layer
*/
virtual QgsRectangle extent();
/**
* Get the number of fields in the layer
*/
uint fieldCount() const { return mAttributeFields.size(); }
/**
* Get the field information for the layer
* @return vector of QgsField objects
*/
const QgsFieldMap & fields() const { return mAttributeFields; }
/**
* Restart reading features from previous select operation
*/
void rewind();
/** Returns the minimum value of an attribute
* @param index the index of the attribute */
QVariant minimumValue( int index ) { return minmaxValue( index, "MIN" ); }
/** Returns the maximum value of an attribute
* @param index the index of the attribute */
QVariant maximumValue( int index ) { return minmaxValue( index, "MAX" ); }
/** Return the unique values of an attribute
* @param index the index of the attribute
* @param values reference to the list of unique values
* @param limit maximum number of values (added in 1.4) */
virtual void uniqueValues( int index, QList < QVariant > &uniqueValues, int limit = -1 );
/**Returns true if layer is valid
*/
bool isValid() { return mValid; }
/**Returns the default value for field specified by @c fieldId */
QVariant defaultValue( int fieldId ) { return mAttributeDefaults[fieldId]; }
/**Adds a list of features
@return true in case of success and false in case of failure*/
bool addFeatures( QgsFeatureList & flist );
/**Deletes a list of features
@param id list of feature ids
@return true in case of success and false in case of failure*/
bool deleteFeatures( const QgsFeatureIds & id );
/**Adds new attributes
@param name map with attribute name as key and type as value
@return true in case of success and false in case of failure*/
bool addAttributes( const QList<QgsField> &attributes );
/**Deletes existing attributes
@param ids of the attributes to delete
@return true in case of success and false in case of failure*/
bool deleteAttributes( const QgsAttributeIds & ids );
/**Changes attribute values of existing features
@param attr_map a map containing the new attributes. The integer is the feature id,
the first QString is the attribute name and the second one is the new attribute value
@return true in case of success and false in case of failure*/
bool changeAttributeValues( const QgsChangedAttributesMap & attr_map );
/**
Changes geometries of existing features
@param geometry_map A std::map containing the feature IDs to change the geometries of.
the second map parameter being the new geometries themselves
@return true in case of success and false in case of failure
*/
bool changeGeometryValues( QgsGeometryMap & geometry_map );
/**Returns a bitmask containing the supported capabilities*/
int capabilities() const { return mCapabilities; }
/** return a provider name
*/
QString name() const;
/** return description
* Return a terse string describing what the provider is.
*/
QString description() const;
private:
/** Returns the minimum value of an attribute
* @param index the index of the attribute */
QVariant minmaxValue( int index, const QString minmax );
/**
* Sets mNumberFeatures
*/
void countFeatures();
/**
* loads fields to member mAttributeFields and mAttributeDefaults
*/
bool loadFields();
/**
* retrieves attribute's default value from database schema
*/
QString getDefaultValue( QString attrName );
/**
* Populates QgsVectorDataProvider::mNativeTypes
*/
void setNativeTypes();
/**
* Sets mKeyColumn and mKeyConstrained
*/
bool findKeyColumn();
/**
* Sets mIsTable, mTableId, mIsComputed, mGeomType, mSrid
*/
bool checkLayerType();
/**
* sets mCrs, mSrsExtent
*/
bool checkSrs();
/**
* Sets mCapabilities
*/
bool checkPermissions();
bool testDMLPermission( QString sql );
bool testDeletePermission();
bool testInsertPermission();
bool testUpdateGeomPermission();
bool testUpdateOtherPermission();
bool testUpdateColumn( QString colname );
bool testAlterTable();
bool testMeasuredOr3D();
/**
* retrieves specified field from mAttributeFields
*/
const QgsField field( int index ) const;
/**
* Ensures that a database connections is live,
* connecting or reconnecting if necessary.
*
* Note that a reconnection automatically invalidates
* the cursors mStmt and mIdStmt.
*/
bool ensureConnRO();
bool ensureConnRW();
/**
* internal utility functions used to handle common database tasks
*/
void closeDb();
void closeCursors() { closeConnROCursors(); }
void closeConnROCursors();
void closeConnRO();
void closeConnRW();
QString quotedIdentifier( QString id ) const;
QString quotedValue( QString value ) const;
QString getWhereClause() const { return mSubsetString.isEmpty() ? "1=1 " : "( " + mSubsetString + ") "; }
bool hasUniqueData( QString colName );
QString makeSelectSql( QString whereClause ) const;
bool nextFeature( QgsFeature & feature, SqlAnyStatement *stmt );
QString geomSampleSet();
QString geomColIdent() const { return quotedIdentifier( mGeometryColumn ) + mGeometryProjStr; }
/**
* static internal utility functions
*/
static QGis::WkbType lookupWkbType( QString type );
static void showMessageBox( const QString& title, const QString& text );
static void showMessageBox( const QString& title, const QStringList& text );
static void reportError( const QString& title, sacapi_i32 code, const char *errbuf );
static void reportError( const QString& title, SqlAnyStatement *stmt );
static void reportError( const QString& title, sacapi_i32 code, QString msg );
private:
/**
* information needed to establish connection
*/
QString mConnectInfo;
/**
* map of field index number to field type
*/
QgsFieldMap mAttributeFields;
/**
* map of field index number to field default value
*/
QMap<int, QString> mAttributeDefaults;
/**
* Flag indicating if the layer data source is a SQL Anywhere layer
*/
bool mValid;
/**
* Use estimated metadata when determining table counts,
* geometry type, and extent.
*/
bool mUseEstimatedMetadata;
/**
* Name of the schema
*/
QString mSchemaName;
/**
* Name of the table with no schema
*/
QString mTableName;
/**
* Internal oid of the table/view
*/
unsigned int mTableId;
/**
* Flag indicating whether this is a table (as compared to a view)
*/
bool mIsTable;
/**
* Name of the table in format "schema"."table"
*/
QString mQuotedTableName;
/**
* Name of the key column used to access the table
*/
QString mKeyColumn;
/**
* Flag indicating whether schema constraint enforces mKeyColumn is unique
*/
bool mKeyConstrained;
/**
* Name of the geometry column in the table
*/
QString mGeometryColumn;
QString mGeometryProjStr;
/**
* Geometry type
*/
QGis::WkbType mGeomType;
/**
* Flag indicating whether mGeometryColumn originates from a
* computed expression
*/
bool mIsComputed;
/**
* Bitmap of capabilities supported for this layer.
* See QgsVectorDataProvider::Capability
*/
int mCapabilities;
/**
* String used to define a subset of the layer
*/
QString mSubsetString;
/**
* Spatial reference id of the layer
*/
int mSrid;
/**
* Definition of the reference system
*/
QgsCoordinateReferenceSystem mCrs;
/**
* SRS boundaries (used to threshold rectangle queries)
*/
QgsRectangle mSrsExtent;
/**
* Rectangle that contains the extent (bounding box) of the layer
*/
QgsRectangle mLayerExtent;
/**
* Number of features in the layer
*/
long mNumberFeatures;
/**
* Statement handle for fetching of features by bounding rectangle
*/
SqlAnyStatement *mStmt;
QgsAttributeList mStmtAttributesToFetch;
bool mStmtFetchGeom;
QgsRectangle mStmtRect;
bool mStmtUseIntersect;
/**
* Statement handle for fetching of features by ID
*/
SqlAnyStatement *mIdStmt;
QgsAttributeList mIdStmtAttributesToFetch;
bool mIdStmtFetchGeom;
/**
* Read-only connection to SQL Anywhere database
*/
SqlAnyConnection *mConnRO;
/**
* Read-write connection to SQL Anywhere database
*/
SqlAnyConnection *mConnRW;
}; // class QgsSqlAnywhereProvider
#endif // QGSSQLANYWHEREPROVIDER_H