Line data Source code
1 : /******************************************************************************
2 : * $Id$
3 : *
4 : * Project: MSSQL Spatial driver
5 : * Purpose: Definition of classes for OGR MSSQL Spatial driver.
6 : * Author: Tamas Szekeres, szekerest at gmail.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2010, Tamas Szekeres
10 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : #ifndef OGR_MSSQLSPATIAL_H_INCLUDED
31 : #define OGR_MSSQLSPATIAL_H_INCLUDED
32 :
33 : #include "ogrsf_frmts.h"
34 : #include "cpl_odbc.h"
35 : #include "cpl_error.h"
36 :
37 : #ifdef SQLNCLI_VERSION
38 : #include <sqlncli.h>
39 : #endif
40 : #ifdef MSODBCSQL_VERSION
41 : #include "include_msodbcsql.h"
42 : #endif
43 :
44 : #include <map>
45 :
46 : class OGRMSSQLSpatialDataSource;
47 :
48 : /* layer status */
49 : #define MSSQLLAYERSTATUS_ORIGINAL 0
50 : #define MSSQLLAYERSTATUS_INITIAL 1
51 : #define MSSQLLAYERSTATUS_CREATED 2
52 : #define MSSQLLAYERSTATUS_DISABLED 3
53 :
54 : /* geometry format to transfer geometry column */
55 : #define MSSQLGEOMETRY_NATIVE 0
56 : #define MSSQLGEOMETRY_WKB 1
57 : #define MSSQLGEOMETRY_WKT 2
58 : #define MSSQLGEOMETRY_WKBZM 3 /* SQL Server 2012 */
59 :
60 : /* geometry column types */
61 : #define MSSQLCOLTYPE_GEOMETRY 0
62 : #define MSSQLCOLTYPE_GEOGRAPHY 1
63 : #define MSSQLCOLTYPE_BINARY 2
64 : #define MSSQLCOLTYPE_TEXT 3
65 :
66 : /* sqlgeometry constants */
67 :
68 : #define VA_KATMAI 0x01
69 : #define VA_DENALI 0x02
70 :
71 : #define SP_NONE 0
72 : #define SP_HASZVALUES 1
73 : #define SP_HASMVALUES 2
74 : #define SP_ISVALID 4
75 : #define SP_ISSINGLEPOINT 8
76 : #define SP_ISSINGLELINESEGMENT 0x10
77 : #define SP_ISLARGERTHANAHEMISPHERE 0x20
78 :
79 : #define ST_UNKNOWN 0
80 : #define ST_POINT 1
81 : #define ST_LINESTRING 2
82 : #define ST_POLYGON 3
83 : #define ST_MULTIPOINT 4
84 : #define ST_MULTILINESTRING 5
85 : #define ST_MULTIPOLYGON 6
86 : #define ST_GEOMETRYCOLLECTION 7
87 : #define ST_CIRCULARSTRING 8
88 : #define ST_COMPOUNDCURVE 9
89 : #define ST_CURVEPOLYGON 10
90 : #define ST_FULLGLOBE 11
91 :
92 : #define FA_INTERIORRING 0x00
93 : #define FA_STROKE 0x01
94 : #define FA_EXTERIORRING 0x02
95 :
96 : #define FA_NONE 0x00
97 : #define FA_LINE 0x01
98 : #define FA_ARC 0x02
99 : #define FA_CURVE 0x03
100 :
101 : #define SMT_LINE 0
102 : #define SMT_ARC 1
103 : #define SMT_FIRSTLINE 2
104 : #define SMT_FIRSTARC 3
105 :
106 : /************************************************************************/
107 : /* OGRMSSQLAppendEscaped( ) */
108 : /************************************************************************/
109 :
110 : void OGRMSSQLAppendEscaped(CPLODBCStatement *poStatement,
111 : const char *pszStrValue);
112 :
113 : /************************************************************************/
114 : /* OGRMSSQLGeometryParser */
115 : /************************************************************************/
116 :
117 : class OGRMSSQLGeometryValidator
118 : {
119 : protected:
120 : bool bIsValid;
121 : OGRGeometry *poValidGeometry;
122 : OGRGeometry *poOriginalGeometry;
123 : int nGeomColumnType;
124 :
125 : public:
126 : explicit OGRMSSQLGeometryValidator(OGRGeometry *poGeom,
127 : int nGeomColumnType);
128 : ~OGRMSSQLGeometryValidator();
129 :
130 : bool IsValidLatLon(double longitude, double latitude);
131 : bool IsValidCircularZ(double z1, double z2);
132 : bool IsValidPolygonRingCount(const OGRCurve *poGeom);
133 : bool IsValidPolygonRingClosed(const OGRCurve *poGeom);
134 : bool IsValid(const OGRPoint *poGeom);
135 : bool IsValid(const OGRMultiPoint *poGeom);
136 : bool IsValid(const OGRCircularString *poGeom);
137 : bool IsValid(const OGRSimpleCurve *poGeom);
138 : bool IsValid(const OGRCompoundCurve *poGeom);
139 : bool IsValid(const OGRMultiLineString *poGeom);
140 : bool IsValid(const OGRCurvePolygon *poGeom);
141 : bool IsValid(const OGRMultiPolygon *poGeom);
142 : bool IsValid(const OGRGeometryCollection *poGeom);
143 : bool IsValid(const OGRGeometry *poGeom);
144 : void MakeValid(OGRPoint *poGeom);
145 : void MakeValid(OGRMultiPoint *poGeom);
146 : void MakeValid(OGRCircularString *poGeom);
147 : void MakeValid(OGRSimpleCurve *poGeom);
148 : void MakeValid(OGRCompoundCurve *poGeom);
149 : void MakeValid(OGRMultiLineString *poGeom);
150 : void MakeValid(OGRPolygon *poGeom);
151 : void MakeValid(OGRCurvePolygon *poGeom);
152 : void MakeValid(OGRMultiPolygon *poGeom);
153 : void MakeValid(OGRGeometryCollection *poGeom);
154 : void MakeValid(OGRGeometry *poGeom);
155 : bool ValidateGeometry(OGRGeometry *poGeom);
156 :
157 : OGRGeometry *GetValidGeometryRef();
158 :
159 0 : bool IsValid()
160 : {
161 0 : return bIsValid;
162 : }
163 : };
164 :
165 : /************************************************************************/
166 : /* OGRMSSQLGeometryParser */
167 : /************************************************************************/
168 :
169 : class OGRMSSQLGeometryParser
170 : {
171 : protected:
172 : unsigned char *pszData;
173 : /* version information */
174 : char chVersion;
175 : /* serialization properties */
176 : char chProps;
177 : /* point array */
178 : int nPointSize;
179 : int nPointPos;
180 : int nNumPoints;
181 : /* figure array */
182 : int nFigurePos;
183 : int nNumFigures;
184 : /* shape array */
185 : int nShapePos;
186 : int nNumShapes;
187 : /* segmenttype array */
188 : int nSegmentPos;
189 : int nNumSegments;
190 : int iSegment;
191 : int nSRSId;
192 : /* geometry or geography */
193 : int nColType;
194 :
195 : protected:
196 : OGRPoint *ReadPoint(int iFigure);
197 : OGRMultiPoint *ReadMultiPoint(int iShape);
198 : OGRErr ReadSimpleCurve(OGRSimpleCurve *poCurve, int iPoint, int iNextPoint);
199 : OGRLineString *ReadLineString(int iFigure);
200 : OGRLinearRing *ReadLinearRing(int iFigure);
201 : OGRMultiLineString *ReadMultiLineString(int iShape);
202 : OGRPolygon *ReadPolygon(int iShape);
203 : OGRMultiPolygon *ReadMultiPolygon(int iShape);
204 : OGRGeometryCollection *ReadGeometryCollection(int iShape);
205 : OGRCircularString *ReadCircularString(int iFigure);
206 : OGRCompoundCurve *ReadCompoundCurve(int iFigure);
207 : void AddCurveSegment(OGRCompoundCurve *poCompoundCurve,
208 : OGRSimpleCurve *poCurve, int iPoint, int iNextPoint);
209 : OGRCurvePolygon *ReadCurvePolygon(int iShape);
210 :
211 : public:
212 : explicit OGRMSSQLGeometryParser(int nGeomColumnType);
213 : OGRErr ParseSqlGeometry(unsigned char *pszInput, int nLen,
214 : OGRGeometry **poGeom);
215 :
216 0 : int GetSRSId()
217 : {
218 0 : return nSRSId;
219 : }
220 : };
221 :
222 : /************************************************************************/
223 : /* OGRMSSQLGeometryWriter */
224 : /************************************************************************/
225 :
226 : class OGRMSSQLGeometryWriter
227 : {
228 : protected:
229 : OGRGeometry *poGeom2;
230 : unsigned char *pszData;
231 : int nLen;
232 : /* version information */
233 : char chVersion;
234 : /* serialization properties */
235 : char chProps;
236 : /* point array */
237 : int nPointSize;
238 : int nPointPos;
239 : int nNumPoints;
240 : int iPoint;
241 : /* figure array */
242 : int nFigurePos;
243 : int nNumFigures;
244 : int iFigure;
245 : /* shape array */
246 : int nShapePos;
247 : int nNumShapes;
248 : int iShape;
249 : /* segmenttype array */
250 : int nSegmentPos;
251 : int nNumSegments;
252 : int iSegment;
253 : int nSRSId;
254 : /* geometry or geography */
255 : int nColType;
256 :
257 : protected:
258 : void WritePoint(OGRPoint *poGeom);
259 : void WritePoint(double x, double y);
260 : void WritePoint(double x, double y, double z);
261 : void WritePoint(double x, double y, double z, double m);
262 : void WriteSimpleCurve(OGRSimpleCurve *poGeom, bool bReversePoints);
263 : void WriteSimpleCurve(OGRSimpleCurve *poGeom, int iStartIndex,
264 : bool bReversePoints);
265 : void WriteSimpleCurve(OGRSimpleCurve *poGeom, int iStartIndex, int nCount,
266 : bool bReversePoints);
267 : void WriteCompoundCurve(OGRCompoundCurve *poGeom);
268 : void WriteCurve(OGRCurve *poGeom, bool bReversePoints);
269 : void WritePolygon(OGRPolygon *poGeom);
270 : void WriteCurvePolygon(OGRCurvePolygon *poGeom);
271 : void WriteGeometryCollection(OGRGeometryCollection *poGeom, int iParent);
272 : void WriteGeometry(OGRGeometry *poGeom, int iParent);
273 : void TrackGeometry(OGRGeometry *poGeom);
274 :
275 : public:
276 : OGRMSSQLGeometryWriter(OGRGeometry *poGeometry, int nGeomColumnType,
277 : int nSRS);
278 : OGRErr WriteSqlGeometry(unsigned char *pszBuffer, int nBufLen);
279 :
280 0 : int GetDataLen()
281 : {
282 0 : return nLen;
283 : }
284 : };
285 :
286 : /************************************************************************/
287 : /* OGRMSSQLSpatialLayer */
288 : /************************************************************************/
289 :
290 : class OGRMSSQLSpatialLayer CPL_NON_FINAL : public OGRLayer
291 : {
292 : protected:
293 : OGRFeatureDefn *poFeatureDefn = nullptr;
294 : int nRawColumns = 0;
295 :
296 : CPLODBCStatement *poStmt = nullptr;
297 : bool m_bEOF = false;
298 : bool m_bResetNeeded = false;
299 :
300 : // Layer spatial reference system, and srid.
301 : OGRSpatialReference *poSRS = nullptr;
302 : int nSRSId = 0;
303 :
304 : GIntBig iNextShapeId = 0;
305 :
306 : OGRMSSQLSpatialDataSource *poDS = nullptr;
307 :
308 : int nGeomColumnType = -1;
309 : char *pszGeomColumn = nullptr;
310 : int nGeomColumnIndex = -1;
311 : char *pszFIDColumn = nullptr;
312 : int nFIDColumnIndex = -1;
313 :
314 : // UUID doesn't work for now in bulk copy mode
315 : bool m_bHasUUIDColumn = false;
316 :
317 : int bIsIdentityFid = FALSE;
318 :
319 : int nLayerStatus = MSSQLLAYERSTATUS_ORIGINAL;
320 :
321 : int *panFieldOrdinals = nullptr;
322 :
323 : void BuildFeatureDefn(const char *pszLayerName, CPLODBCStatement *poStmt);
324 :
325 0 : virtual CPLODBCStatement *GetStatement()
326 : {
327 0 : return poStmt;
328 : }
329 :
330 : void ClearStatement();
331 : OGRFeature *GetNextRawFeature();
332 : bool bLayerDefnNeedsRefresh = false;
333 :
334 : public:
335 : explicit OGRMSSQLSpatialLayer(OGRMSSQLSpatialDataSource *);
336 : virtual ~OGRMSSQLSpatialLayer();
337 :
338 : virtual void ResetReading() override;
339 : virtual OGRFeature *GetNextFeature() override;
340 :
341 : virtual OGRFeature *GetFeature(GIntBig nFeatureId) override;
342 :
343 0 : virtual OGRFeatureDefn *GetLayerDefn() override
344 : {
345 0 : return poFeatureDefn;
346 : }
347 :
348 : virtual OGRSpatialReference *GetSpatialRef() override;
349 :
350 : virtual OGRErr StartTransaction() override;
351 : virtual OGRErr CommitTransaction() override;
352 : virtual OGRErr RollbackTransaction() override;
353 :
354 : virtual const char *GetFIDColumn() override;
355 : virtual const char *GetGeometryColumn() override;
356 :
357 : virtual int TestCapability(const char *) override;
358 : static char *GByteArrayToHexString(const GByte *pabyData, int nLen);
359 :
360 0 : void SetLayerStatus(int nStatus)
361 : {
362 0 : nLayerStatus = nStatus;
363 0 : }
364 :
365 0 : int GetLayerStatus()
366 : {
367 0 : return nLayerStatus;
368 : }
369 :
370 : GDALDataset *GetDataset() override;
371 : };
372 :
373 : /************************************************************************/
374 : /* OGRMSSQLSpatialTableLayer */
375 : /************************************************************************/
376 :
377 : typedef union
378 : {
379 : struct
380 : {
381 : int iIndicator;
382 : int Value;
383 : } Integer;
384 :
385 : struct
386 : {
387 : int iIndicator;
388 : GIntBig Value;
389 : } Integer64;
390 :
391 : struct
392 : {
393 : int iIndicator;
394 : double Value;
395 : } Float;
396 :
397 : struct
398 : {
399 : SQLLEN nSize;
400 : char *pData[8000];
401 : } VarChar;
402 :
403 : struct
404 : {
405 : SQLLEN nSize;
406 : GByte *pData;
407 : } RawData;
408 :
409 : } BCPData;
410 :
411 : class OGRMSSQLSpatialTableLayer final : public OGRMSSQLSpatialLayer
412 : {
413 : bool bUpdateAccess = true;
414 : bool bUseGeometryValidation = false;
415 : int bLaunderColumnNames = FALSE;
416 : int bPreservePrecision = FALSE;
417 : int bNeedSpatialIndex = FALSE;
418 : int bUseCopy = FALSE;
419 : int nBCPSize = 1000;
420 :
421 : #ifdef SQL_SS_UDT
422 : int nUploadGeometryFormat = MSSQLGEOMETRY_NATIVE;
423 : #else
424 : int nUploadGeometryFormat = MSSQLGEOMETRY_WKB;
425 : #endif
426 :
427 : char *pszQuery = nullptr;
428 :
429 : SQLHANDLE hEnvBCP = nullptr;
430 : #ifdef MSSQL_BCP_SUPPORTED
431 : SQLHANDLE hDBCBCP = nullptr;
432 : int nBCPCount = 0;
433 : BCPData **papstBindBuffer = nullptr;
434 :
435 : int bIdentityInsert = FALSE;
436 : #endif
437 :
438 : CPLODBCStatement *BuildStatement(const char *pszColumns);
439 :
440 : CPLString BuildFields();
441 :
442 : virtual CPLODBCStatement *GetStatement() override;
443 :
444 : char *pszTableName = nullptr;
445 : char *pszLayerName = nullptr;
446 : char *pszSchemaName = nullptr;
447 :
448 : OGRwkbGeometryType eGeomType = wkbNone;
449 :
450 : public:
451 : explicit OGRMSSQLSpatialTableLayer(OGRMSSQLSpatialDataSource *);
452 : virtual ~OGRMSSQLSpatialTableLayer();
453 :
454 : CPLErr Initialize(const char *pszSchema, const char *pszTableName,
455 : const char *pszGeomCol, int nCoordDimension, int nSRId,
456 : const char *pszSRText, OGRwkbGeometryType eType);
457 :
458 : OGRErr CreateSpatialIndex();
459 : void DropSpatialIndex();
460 :
461 0 : virtual OGRErr GetExtent(OGREnvelope *psExtent, int bForce) override
462 : {
463 0 : return GetExtent(0, psExtent, bForce);
464 : }
465 :
466 : virtual OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent,
467 : int bForce) override;
468 :
469 : virtual GIntBig GetFeatureCount(int) override;
470 :
471 : virtual OGRFeatureDefn *GetLayerDefn() override;
472 :
473 : virtual const char *GetName() override;
474 :
475 : virtual OGRErr SetAttributeFilter(const char *) override;
476 : virtual OGRFeature *GetNextFeature() override;
477 :
478 : virtual OGRErr ISetFeature(OGRFeature *poFeature) override;
479 : virtual OGRErr DeleteFeature(GIntBig nFID) override;
480 : virtual OGRErr ICreateFeature(OGRFeature *poFeature) override;
481 :
482 0 : const char *GetTableName()
483 : {
484 0 : return pszTableName;
485 : }
486 :
487 : const char *GetLayerName()
488 : {
489 : return pszLayerName;
490 : }
491 :
492 0 : const char *GetSchemaName()
493 : {
494 0 : return pszSchemaName;
495 : }
496 :
497 : virtual OGRErr CreateField(const OGRFieldDefn *poField,
498 : int bApproxOK = TRUE) override;
499 :
500 : virtual OGRFeature *GetFeature(GIntBig nFeatureId) override;
501 :
502 : virtual int TestCapability(const char *) override;
503 :
504 0 : void SetLaunderFlag(int bFlag)
505 : {
506 0 : bLaunderColumnNames = bFlag;
507 0 : }
508 :
509 0 : void SetPrecisionFlag(int bFlag)
510 : {
511 0 : bPreservePrecision = bFlag;
512 0 : }
513 :
514 0 : void SetSpatialIndexFlag(int bFlag)
515 : {
516 0 : bNeedSpatialIndex = bFlag;
517 0 : }
518 :
519 0 : void SetUploadGeometryFormat(int nGeometryFormat)
520 : {
521 0 : nUploadGeometryFormat = nGeometryFormat;
522 0 : }
523 :
524 : void AppendFieldValue(CPLODBCStatement *poStatement, OGRFeature *poFeature,
525 : int i, int *bind_num, void **bind_buffer);
526 :
527 : int FetchSRSId();
528 :
529 0 : void SetUseCopy(int bcpSize)
530 : {
531 0 : bUseCopy = TRUE;
532 0 : nBCPSize = bcpSize;
533 0 : }
534 :
535 0 : void SetUpdate(bool bFlag)
536 : {
537 0 : bUpdateAccess = bFlag;
538 0 : }
539 :
540 : // cppcheck-suppress functionStatic
541 : OGRErr StartCopy();
542 : // cppcheck-suppress functionStatic
543 : OGRErr EndCopy();
544 :
545 : int Failed(int nRetCode);
546 : #ifdef MSSQL_BCP_SUPPORTED
547 : OGRErr CreateFeatureBCP(OGRFeature *poFeature);
548 : int Failed2(int nRetCode);
549 : int InitBCP(const char *pszDSN);
550 : void CloseBCP();
551 : #endif
552 : };
553 :
554 : /************************************************************************/
555 : /* OGRMSSQLSpatialSelectLayer */
556 : /************************************************************************/
557 :
558 : class OGRMSSQLSpatialSelectLayer final : public OGRMSSQLSpatialLayer
559 : {
560 : char *pszBaseStatement;
561 :
562 : virtual CPLODBCStatement *GetStatement() override;
563 :
564 : public:
565 : OGRMSSQLSpatialSelectLayer(OGRMSSQLSpatialDataSource *, CPLODBCStatement *);
566 : virtual ~OGRMSSQLSpatialSelectLayer();
567 :
568 : virtual GIntBig GetFeatureCount(int) override;
569 :
570 : virtual OGRFeature *GetFeature(GIntBig nFeatureId) override;
571 :
572 : virtual OGRErr GetExtent(OGREnvelope *psExtent, int bForce = TRUE) override;
573 :
574 0 : virtual OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent,
575 : int bForce) override
576 : {
577 0 : return OGRLayer::GetExtent(iGeomField, psExtent, bForce);
578 : }
579 :
580 : virtual int TestCapability(const char *) override;
581 : };
582 :
583 : /************************************************************************/
584 : /* OGRODBCDataSource */
585 : /************************************************************************/
586 :
587 : class OGRMSSQLSpatialDataSource final : public OGRDataSource
588 : {
589 : typedef struct
590 : {
591 : int nMajor;
592 : int nMinor;
593 : int nBuild;
594 : int nRevision;
595 : } MSSQLVer;
596 :
597 : OGRMSSQLSpatialTableLayer **papoLayers;
598 : int nLayers;
599 :
600 : char *pszName;
601 :
602 : char *pszCatalog;
603 :
604 : bool bDSUpdate;
605 : CPLODBCSession oSession;
606 :
607 : int nGeometryFormat;
608 :
609 : int bUseGeometryColumns;
610 : bool bAlwaysOutputFid;
611 :
612 : int bListAllTables;
613 :
614 : int nBCPSize;
615 : int bUseCopy;
616 :
617 : // We maintain a list of known SRID to reduce the number of trips to
618 : // the database to get SRSes.
619 : std::map<int,
620 : std::unique_ptr<OGRSpatialReference, OGRSpatialReferenceReleaser>>
621 : m_oSRSCache{};
622 :
623 : OGRMSSQLSpatialTableLayer *poLayerInCopyMode;
624 :
625 : static void OGRMSSQLDecodeVersionString(MSSQLVer *psVersion,
626 : const char *pszVer);
627 :
628 : char *pszConnection;
629 :
630 : public:
631 : MSSQLVer sMSSQLVersion;
632 :
633 : OGRMSSQLSpatialDataSource();
634 : virtual ~OGRMSSQLSpatialDataSource();
635 :
636 0 : const char *GetCatalog()
637 : {
638 0 : return pszCatalog;
639 : }
640 :
641 : static int ParseValue(char **pszValue, char *pszSource, const char *pszKey,
642 : int nStart, int nNext, int nTerm, int bRemove);
643 :
644 : int Open(const char *, bool bUpdate, int bTestOpen);
645 : int OpenTable(const char *pszSchemaName, const char *pszTableName,
646 : const char *pszGeomCol, int nCoordDimension, int nSRID,
647 : const char *pszSRText, OGRwkbGeometryType eType,
648 : bool bUpdate);
649 :
650 0 : const char *GetName() override
651 : {
652 0 : return pszName;
653 : }
654 :
655 : int GetLayerCount() override;
656 : OGRLayer *GetLayer(int) override;
657 : OGRLayer *GetLayerByName(const char *pszLayerName) override;
658 :
659 0 : int GetGeometryFormat()
660 : {
661 0 : return nGeometryFormat;
662 : }
663 :
664 0 : int UseGeometryColumns()
665 : {
666 0 : return bUseGeometryColumns;
667 : }
668 :
669 0 : bool AlwaysOutputFid()
670 : {
671 0 : return bAlwaysOutputFid;
672 : }
673 :
674 : virtual OGRErr DeleteLayer(int iLayer) override;
675 : OGRLayer *ICreateLayer(const char *pszName,
676 : const OGRGeomFieldDefn *poGeomFieldDefn,
677 : CSLConstList papszOptions) override;
678 :
679 : int TestCapability(const char *) override;
680 :
681 : virtual OGRLayer *ExecuteSQL(const char *pszSQLCommand,
682 : OGRGeometry *poSpatialFilter,
683 : const char *pszDialect) override;
684 : virtual void ReleaseResultSet(OGRLayer *poLayer) override;
685 :
686 : static char *LaunderName(const char *pszSrcName);
687 : OGRErr InitializeMetadataTables();
688 :
689 : OGRSpatialReference *AddSRIDToCache(
690 : int nId,
691 : std::unique_ptr<OGRSpatialReference, OGRSpatialReferenceReleaser>
692 : &&poSRS);
693 :
694 : OGRSpatialReference *FetchSRS(int nId);
695 : int FetchSRSId(const OGRSpatialReference *poSRS);
696 :
697 : OGRErr StartTransaction(CPL_UNUSED int bForce) override;
698 : OGRErr CommitTransaction() override;
699 : OGRErr RollbackTransaction() override;
700 :
701 : // Internal use
702 0 : CPLODBCSession *GetSession()
703 : {
704 0 : return &oSession;
705 : }
706 :
707 : const char *GetConnectionString()
708 : {
709 : return pszConnection;
710 : }
711 :
712 : void StartCopy(OGRMSSQLSpatialTableLayer *poMSSQLSpatialLayer);
713 : OGRErr EndCopy();
714 : };
715 :
716 : #endif /* ndef OGR_MSSQLSPATIAL_H_INCLUDED */
|