1 /*****************************************************************************
2  *
3  * Project:  DB2 Spatial driver
4  * Purpose:  Definition of classes for OGR DB2 Spatial driver.
5  * Author:   David Adler, dadler at adtechgeospatial dot com
6  *
7  *****************************************************************************
8  * Copyright (c) 2010, Tamas Szekeres
9  * Copyright (c) 2015, David Adler
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_DB2_H_INCLUDED
31 #define OGR_DB2_H_INCLUDED
32 #ifdef DB2_CLI
33 #include <sqlcli1.h>   // needed for CLI support
34 #endif
35 #include "ogrsf_frmts.h"
36 #include "cpl_port.h"
37 #include "cpl_error.h"
38 #include "gdal_pam.h"
39 #include "gdalwarper.h"
40 #include <time.h>
41 
42 #ifdef WIN32
43 #  include <windows.h>
44 #endif
45 
46 #ifndef DB2_CLI
47 #include <sql.h>
48 #include <sqlext.h>
49 #endif
50 #include <odbcinst.h>
51 #include "cpl_string.h"
52 
53 // Map ODBC handles to DB2 CLI handles
54 #ifndef HDBC
55 #define HDBC SQLHDBC
56 #define HSTMT SQLHSTMT
57 #define HENV SQLHENV
58 #endif
59 
60 #ifdef PATH_MAX
61 #  define ODBC_FILENAME_MAX PATH_MAX
62 #else
63 #  define ODBC_FILENAME_MAX (255 + 1) /* Max path length */
64 #endif
65 
66 class OGRDB2DataSource;
67 
68 #ifdef DEBUG_SQL
69 #define DB2_DEBUG_SQL(ogrdb2fn,ogrdb2stmt) \
70               CPLDebug(ogrdb2fn, "stmt: '%s'", ogrdb2stmt.GetCommand());
71 #else
72 #define DB2_DEBUG_SQL(ogrdb2fn,ogrdb2stmt)
73 #endif
74 
75 #ifdef DEBUG_DB2
76 #define DB2_DEBUG_ENTER(ogrdb2fn) \
77             CPLDebug(ogrdb2fn,"Entering");
78 
79 #define DB2_DEBUG_EXIT(ogrdb2fn) \
80             CPLDebug(ogrdb2fn,"Exiting");
81 
82 #else
83 #define DB2_DEBUG_ENTER(ogrdb2fn)
84 #define DB2_DEBUG_EXIT(ogrdb2fn)
85 #endif
86 
87 #define DB2ODBC_PREFIX "DB2ODBC:"
88 
89 #define UNKNOWN_SRID   -2
90 #define DEFAULT_SRID    0
91 
92 // LATER - not sure what the maximum blob size should be
93 #define MAXBLOB 1000000
94 
95 class GDALDB2RasterBand;
96 class OGRDB2TableLayer;
97 
98 typedef struct
99 {
100     int     nRow;
101     int     nCol;
102     int     nIdxWithinTileData;
103     int     abBandDirty[4];
104 } CachedTileDesc;
105 
106 typedef enum
107 {
108     GPKG_TF_PNG_JPEG,
109     GPKG_TF_PNG,
110     GPKG_TF_PNG8,
111     GPKG_TF_JPEG,
112     GPKG_TF_WEBP
113 } GPKGTileFormat;
114 
115 /* On MSVC SQLULEN is missing in some cases (i.e. VC6)
116 ** but it is always a #define so test this way.   On Unix
117 ** it is a typedef so we can't always do this.
118 */
119 #if defined(_MSC_VER) && !defined(SQLULEN) && !defined(_WIN64)
120 #  define MISSING_SQLULEN
121 #endif
122 
123 #if !defined(MISSING_SQLULEN)
124 /* ODBC types to support 64 bit compilation */
125 #  define CPL_SQLULEN SQLULEN
126 #  define CPL_SQLLEN  SQLLEN
127 #else
128 #  define CPL_SQLULEN SQLUINTEGER
129 #  define CPL_SQLLEN  SQLINTEGER
130 #endif  /* ifdef SQLULEN */
131 
132 /**
133  * A class representing an ODBC database session.
134  *
135  * Includes error collection services.
136  *
137  * Copied from cpl_odbc.h - to resolve issue with needing to include
138  * different header files for ODBC and CLI.
139  */
140 
141 /************************************************************************/
142 /*                             OGRDB2Session                            */
143 /************************************************************************/
144 
145 class OGRDB2Session
146 {
147 protected:
148 // From CPLODBCSession
149     char      m_szLastError[SQL_MAX_MESSAGE_LENGTH + 1];
150     HENV      m_hEnv = nullptr;
151     HDBC      m_hDBC = nullptr;
152     int       m_bInTransaction = FALSE;
153     int       m_bAutoCommit = TRUE;
154 
155 public:
156     OGRDB2Session( );
157     virtual ~OGRDB2Session();
158 // From CPLODBCSession
159     int         EstablishSession( const char *pszDSN,
160                                   const char *pszUserid,
161                                   const char *pszPassword );
162     const char  *GetLastError();
163 
164     // Transaction handling
165 
166     int         ClearTransaction();
167     int         BeginTransaction();
168     int         CommitTransaction();
169     virtual int RollbackTransaction();
IsInTransaction()170     int         IsInTransaction() { return m_bInTransaction; }
171 
172     // Essentially internal.
173 
174     int         CloseSession();
175 
176     int         Failed( int, HSTMT = nullptr );
GetConnection()177     HDBC        GetConnection() { return m_hDBC; }
GetEnvironment()178     HENV        GetEnvironment()  { return m_hEnv; }
179 };
180 
181 /**
182  * Abstraction for statement, and resultset.
183  *
184  * Includes methods for executing an SQL statement, and for accessing the
185  * resultset from that statement.  Also provides for executing other ODBC
186  * requests that produce results sets such as SQLColumns() and SQLTables()
187  * requests.
188  *
189  * Copied from cpl_odbc.h - to resolve issue with needing to include
190  * different header files for ODBC and CLI
191  */
192 
193 /************************************************************************/
194 /*                             OGRDB2Statement                          */
195 /************************************************************************/
196 
197 class OGRDB2Statement
198 {
199 protected:
200     int             m_nLastRetCode;
201     int             m_bPrepared;
202 // From CPLODBCStatement
203     OGRDB2Session     *m_poSession;
204     HSTMT               m_hStmt;
205 
206     SQLSMALLINT    m_nColCount;
207     char         **m_papszColNames;
208     SQLSMALLINT   *m_panColType;
209     char         **m_papszColTypeNames;
210     CPL_SQLULEN      *m_panColSize;
211     SQLSMALLINT   *m_panColPrecision;
212     SQLSMALLINT   *m_panColNullable;
213     char         **m_papszColColumnDef;
214 
215     char         **m_papszColValues;
216     CPL_SQLLEN       *m_panColValueLengths;
217 
218     char          *m_pszStatement;
219     size_t         m_nStatementMax;
220     size_t         m_nStatementLen;
221 public:
222     explicit OGRDB2Statement( OGRDB2Session * );
223     OGRDB2Statement( );
224     ~OGRDB2Statement();
225     int             DB2Execute(const char *pszCallingFunction);
226     int             DB2Prepare(const char *pszCallingFunction);
GetLastRetCode()227     int             GetLastRetCode() {
228         return m_nLastRetCode;
229     };
230     int             DB2BindParameterIn(const char *pszCallingFunction,
231                                             int nBindNum,
232                                             int nValueType,
233                                             int nParameterType,
234                                             int nLen,
235                                             void * pValuePointer);
236 
237 // From CPLODBCStatement
GetStatement()238     HSTMT          GetStatement() { return m_hStmt; }
239     int            Failed( int );
240     // Command buffer related.
241     void           Clear();
242     void           AppendEscaped( const char * );
243     void           Append( const char * );
244     void           Append( int );
245     void           Append( double );
246     int            Appendf( const char *, ... ) CPL_PRINT_FUNC_FORMAT (2, 3);
GetCommand()247     const char    *GetCommand() { return m_pszStatement; }
248 
249     int            ExecuteSQL( const char * = nullptr );
250 
251     // Results fetching
252     int            Fetch( int nOrientation = SQL_FETCH_NEXT,
253                           int nOffset = 0 );
254     void           ClearColumnData();
255 
256     int            GetColCount();
257     const char    *GetColName( int );
258     short          GetColType( int );
259     const char    *GetColTypeName( int );
260     short          GetColSize( int );
261     short          GetColPrecision( int );
262     short          GetColNullable( int );
263     const char    *GetColColumnDef( int );
264 
265     int            GetColId( const char * );
266     const char    *GetColData( int, const char * = nullptr );
267     const char    *GetColData( const char *, const char * = nullptr );
268     int            GetColDataLength( int );
269     int            GetRowCountAffected();
270 
271     // Fetch special metadata.
272     int            GetColumns( const char *pszTable,
273                                const char *pszCatalog = nullptr,
274                                const char *pszSchema = nullptr );
275     int            GetPrimaryKeys( const char *pszTable,
276                                    const char *pszCatalog = nullptr,
277                                    const char *pszSchema = nullptr );
278 
279     int            GetTables( const char *pszCatalog = nullptr,
280                               const char *pszSchema = nullptr );
281 
282     void           DumpResult( FILE *fp, int bShowSchema = FALSE );
283 
284     static CPLString GetTypeName( int );
285     static SQLSMALLINT GetTypeMapping( SQLSMALLINT );
286 
287     int            CollectResultsInfo();
288 };
289 
290 /************************************************************************/
291 /*                         OGRDB2AppendEscaped( )                       */
292 /************************************************************************/
293 
294 void OGRDB2AppendEscaped( OGRDB2Statement* poStatement,
295                           const char* pszStrValue);
296 
297 /************************************************************************/
298 /*                             OGRDB2Layer                              */
299 /************************************************************************/
300 
301 class OGRDB2Layer CPL_NON_FINAL: public OGRLayer
302 {
303 protected:
304     OGRDB2DataSource *m_poDS; // GPKG - where set?
305     OGRFeatureDefn     *poFeatureDefn;
306 
307     OGRDB2Statement   *m_poStmt;
308 
309     OGRDB2Statement   *m_poPrepStmt;
310 
311     // Layer spatial reference system, and srid.
312     OGRSpatialReference *poSRS;
313     int                 nSRSId;
314 
315     GIntBig            iNextShapeId;
316 
317     OGRDB2DataSource   *poDS;
318 
319     char               *pszGeomColumn;
320     char               *pszFIDColumn;
321 
322     int                bIsIdentityFid;
323     char               cGenerated;// 'A' always generated, 'D' default,' ' not
324     int                nLayerStatus;
325     int                *panFieldOrdinals;
326 
327     CPLErr             BuildFeatureDefn( const char *pszLayerName,
328                                          OGRDB2Statement *poStmt );
329 
GetStatement()330     virtual OGRDB2Statement *  GetStatement() {
331         return m_poStmt;
332     }
333 
334 public:
335     OGRDB2Layer();
336     virtual             ~OGRDB2Layer();
337 
338     virtual void        ResetReading() override;
339     virtual OGRFeature *GetNextRawFeature();
340     virtual OGRFeature *GetNextFeature() override;
341 
342     virtual OGRFeature *GetFeature( GIntBig nFeatureId ) override;
343 
GetLayerDefn()344     virtual OGRFeatureDefn *GetLayerDefn() override {
345         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     char*               GByteArrayToHexString( const GByte* pabyData,
359             int nLen);
360 
SetLayerStatus(int nStatus)361     void               SetLayerStatus( int nStatus ) {
362         nLayerStatus = nStatus;
363     }
GetLayerStatus()364     int                GetLayerStatus() {
365         return nLayerStatus;
366     }
GetSRSId()367     int                GetSRSId() {
368         return nSRSId;
369     }
370 };
371 
372 /************************************************************************/
373 /*                       OGRDB2TableLayer                               */
374 /************************************************************************/
375 
376 class OGRDB2TableLayer final: public OGRDB2Layer
377 {
378     int                 bUpdateAccess;
379     int                 bLaunderColumnNames;
380     int                 bPreservePrecision;
381     int                 bNeedSpatialIndex;
382 
383     //int                 nUploadGeometryFormat;
384     char                *m_pszQuery;
385 
386     void                ClearStatement();
387     OGRDB2Statement* BuildStatement(const char* pszColumns);
388     static void                FreeBindBuffer(int nBindNum, void **bind_buffer);
389     CPLString BuildFields();
390 
391     virtual OGRDB2Statement *  GetStatement() override;
392 
393     char               *pszTableName;
394     char               *m_pszLayerName;
395     char               *pszSchemaName;
396 
397     OGRwkbGeometryType eGeomType;
398 
399 // From GPKG
400     //char*                       m_pszTableName;
401     int                         m_iSrs;
402     //OGREnvelope*                m_poExtent;
403     CPLString                   m_soColumns;
404     CPLString                   m_soFilter;
405     CPLString                   osQuery;
406     //OGRBoolean                  m_bExtentChanged;
407 
408     //int                         m_bInsertStatementWithFID;
409 
410     //int                         bDeferredSpatialIndexCreation;
411     //int                         m_bHasSpatialIndex;
412     //int                         bDropRTreeTable;
413     //int                         m_anHasGeometryExtension[wkbMultiSurface+1];
414     //int                         m_bPreservePrecision;
415     //int                         m_bTruncateFields;
416     //int                         m_bDeferredCreation;
417     //int                         m_iFIDAsRegularColumnIndex;
418 
419     CPLString                   m_osIdentifierLCO;
420     CPLString                   m_osDescriptionLCO;
421     //int                         m_bHasReadMetadataFromStorage;
422     OGRErr              RegisterGeometryColumn();
423     void                BuildWhere();
424 //    OGRErr              SyncToDisk();
425 
426     OGRErr              BindFieldValue(OGRDB2Statement *poStatement,
427                                        OGRFeature* poFeature, int i,
428                                        int nBindNum, void **papBindBuffer);
429 
430 public:
431     explicit OGRDB2TableLayer( OGRDB2DataSource * );
432     virtual ~OGRDB2TableLayer();
433 
434     CPLErr              Initialize( const char *pszSchema,
435                                     const char *pszTableName,
436                                     const char *pszGeomCol,
437                                     int nCoordDimension,
438                                     int nSRId,
439                                     const char *pszSRText,
440                                     OGRwkbGeometryType eType);
441     static OGRErr              isFieldTypeSupported( OGRFieldType nFieldType );
442     OGRErr              CreateSpatialIndex();
443     void                DropSpatialIndex();
444 
445     virtual void        ResetReading() override;
446     virtual GIntBig         GetFeatureCount( int ) override;
447 
448     virtual OGRFeatureDefn *GetLayerDefn() override;
449 
450     virtual const char* GetName() override;
451 
452     virtual OGRErr      SetAttributeFilter( const char * ) override;
453 
454     virtual OGRErr      ISetFeature( OGRFeature *poFeature ) override;
455     virtual OGRErr      DeleteFeature( GIntBig nFID ) override;
456     virtual OGRErr      ICreateFeature( OGRFeature *poFeature ) override;
457     virtual OGRErr      PrepareFeature( OGRFeature *poFeature, char cType );
458 
GetTableName()459     const char*         GetTableName() {
460         return pszTableName;
461     }
GetLayerName()462     const char*         GetLayerName() {
463         return m_pszLayerName;
464     }
GetSchemaName()465     const char*         GetSchemaName() {
466         return pszSchemaName;
467     }
468 
469     virtual OGRErr      CreateField( OGRFieldDefn *poField,
470                                      int bApproxOK = TRUE ) override;
471 
472     virtual OGRFeature *GetFeature( GIntBig nFeatureId ) override;
473 
474     virtual int         TestCapability( const char * ) override;
475 
SetLaunderFlag(int bFlag)476     void                SetLaunderFlag( int bFlag )
477     {
478         bLaunderColumnNames = bFlag;
479     }
SetPrecisionFlag(int bFlag)480     void                SetPrecisionFlag( int bFlag )
481     {
482         bPreservePrecision = bFlag;
483     }
SetSpatialIndexFlag(int bFlag)484     void                SetSpatialIndexFlag( int bFlag )
485     {
486         bNeedSpatialIndex = bFlag;
487     }
488 
489     int                 FetchSRSId();
490     //void                CreateSpatialIndexIfNecessary();
491 
492     int                 DropSpatialIndex(int bCalledFromSQLFunction = FALSE);
493     /*
494         virtual char **     GetMetadata( const char *pszDomain = NULL );
495         virtual const char *GetMetadataItem( const char * pszName,
496                                              const char * pszDomain = "" );
497         virtual char **     GetMetadataDomainList();
498 
499         virtual CPLErr      SetMetadata( char ** papszMetadata,
500                                          const char * pszDomain = "" );
501         virtual CPLErr      SetMetadataItem( const char * pszName,
502                                              const char * pszValue,
503                                              const char * pszDomain = "" );
504 
505         void                RenameTo(const char* pszDstTableName);
506 
507         virtual int          HasFastSpatialFilter(int iGeomCol);
508         virtual CPLString    GetSpatialWhere(int iGeomCol,
509                                              OGRGeometry* poFilterGeom);
510 
511         int                 HasSpatialIndex();
512         void                SetTruncateFieldsFlag( int bFlag )
513         {
514             m_bTruncateFields = bFlag;
515         }
516 
517         OGRErr              ReadTableDefinition(int bIsSpatial);
518         void                SetCreationParameters( OGRwkbGeometryType eGType,
519                 const char* pszGeomColumnName,
520                 int bGeomNullable,
521                 OGRSpatialReference* poSRS,
522                 const char* pszFIDColumnName,
523                 const char* pszIdentifier,
524                 const char* pszDescription );
525     */
526     // cppcheck-suppress functionStatic
527     OGRErr              RunDeferredCreationIfNecessary();
528     /************************************************************************/
529     /* GPKG methods */
530 
531 private:
532 
533     OGRErr              UpdateExtent( const OGREnvelope *poExtent );
534     OGRErr              SaveExtent();
535     OGRErr              BuildColumns();
536     OGRBoolean          IsGeomFieldSet( OGRFeature *poFeature );
537     void                CheckUnknownExtensions();
538     int                 CreateGeometryExtensionIfNecessary(
539                                 OGRwkbGeometryType eGType);
540 };
541 
542 /************************************************************************/
543 /*                      OGRDB2SelectLayer                      */
544 /************************************************************************/
545 
546 class OGRDB2SelectLayer final: public OGRDB2Layer
547 {
548     char                *pszBaseStatement;
549 
550     void                ClearStatement();
551     OGRErr              ResetStatement();
552 
553     virtual OGRDB2Statement *  GetStatement() override;
554 
555 public:
556     OGRDB2SelectLayer( OGRDB2DataSource *,
557                        OGRDB2Statement * );
558     virtual ~OGRDB2SelectLayer();
559 
560     virtual void        ResetReading() override;
561     virtual GIntBig     GetFeatureCount( int ) override;
562 
563     virtual OGRFeature *GetFeature( GIntBig nFeatureId ) override;
564 
565     virtual OGRErr      GetExtent(OGREnvelope *psExtent, int bForce = TRUE) override;
GetExtent(int iGeomField,OGREnvelope * psExtent,int bForce)566      virtual OGRErr      GetExtent(int iGeomField, OGREnvelope *psExtent, int bForce) override
567             { return OGRLayer::GetExtent(iGeomField, psExtent, bForce); }
568 
569     virtual int         TestCapability( const char * ) override;
570 };
571 
572 /************************************************************************/
573 /*                           OGRDB2DataSource                           */
574 /************************************************************************/
575 
576 class OGRDB2DataSource final: public GDALPamDataset
577 {
578     friend class GDALDB2RasterBand;
579     friend class OGRDB2TableLayer;
580 
581 // Utility stuff
582     double              clock1, clock2;
583     time_t              time1, time2;
584     double              dtime;
585     double              dclock;
586     char                stime[256];
587     double              getDTime();
588 
589     char                **m_papszTableNames;
590     char                **m_papszSchemaNames;
591     char                **m_papszGeomColumnNames;
592     char                **m_papszCoordDimensions;
593     char                **m_papszSRIds;
594     char                **m_papszSRTexts;
595     char                *m_pszFilename;
596     int                 m_bIsVector;
597 
598     OGRDB2TableLayer    **papoLayers;
599     OGRDB2TableLayer    **m_papoLayers;    //DWA
600 
601     char               *m_pszName;
602 
603     char               *m_pszCatalog;
604     int                 m_bIsZ;
605     int                 bDSUpdate;
606     OGRDB2Session       m_oSession;
607 
608     int                 bUseGeometryColumns;
609 
610     int                 bListAllTables;
611     int                 m_bHasMetadataTables;
612     // We maintain a list of known SRID to reduce the number of trips to
613     // the database to get SRSes.
614     int                 m_nKnownSRID;
615     int                *m_panSRID;
616     OGRSpatialReference **m_papoSRS;
617 //***************** For raster support
618     int                 m_bUpdate;
619     int                 m_nLayers;
620     int                 m_bUtf8;
621     void                CheckUnknownExtensions(int bCheckRasterTable = FALSE);
622 
623     int                 m_bNew;
624 
625     CPLString           m_osRasterTable;
626     CPLString           m_osIdentifier;
627     int                 m_bIdentifierAsCO;
628     CPLString           m_osDescription;
629     int                 m_bDescriptionAsCO;
630     int                 m_bHasReadMetadataFromStorage;
631     int                 m_bMetadataDirty;
632     char              **m_papszSubDatasets;
633     char               *m_pszProjection;
634     int                 m_bRecordInsertedInGPKGContent;
635     int                 m_bGeoTransformValid;
636     double              m_adfGeoTransform[6];
637     int                 m_nSRID;
638     double              m_dfTMSMinX;
639     double              m_dfTMSMaxY;
640     int                 m_nZoomLevel;
641     GByte              *m_pabyCachedTiles;
642     CachedTileDesc      m_asCachedTilesDesc[4];
643     int                 m_nShiftXTiles;
644     int                 m_nShiftXPixelsMod;
645     int                 m_nShiftYTiles;
646     int                 m_nShiftYPixelsMod;
647     int                 m_nTileMatrixWidth;
648     int                 m_nTileMatrixHeight;
649 
650     GPKGTileFormat      m_eTF;
651     int                 m_nZLevel;
652     int                 m_nQuality;
653     int                 m_bDither;
654 
655     GDALColorTable*     m_poCT;
656     int                 m_bTriedEstablishingCT;
657     GByte*              m_pabyHugeColorArray;
658 
659     OGRDB2DataSource* m_poParentDS;
660     int                 m_nOverviewCount;
661     OGRDB2DataSource** m_papoOverviewDS;
662     int                 m_bZoomOther;
663 
664     CPLString           m_osWHERE;
665 
666     //int                 m_hTempDB;  //LATER - flag that partial_tiles exists
667     CPLString           m_osTempDBFilename;
668 
669     int                 m_bInFlushCache;
670 
671     int                 m_nTileInsertionCount;
672 
673     CPLString           m_osTilingScheme;
674 
675     void            ComputeTileAndPixelShifts();
676     int             InitRaster ( OGRDB2DataSource* poParentDS,
677                                  const char* pszTableName,
678                                  double dfMinX,
679                                  double dfMinY,
680                                  double dfMaxX,
681                                  double dfMaxY,
682                                  const char* pszContentsMinX,
683                                  const char* pszContentsMinY,
684                                  const char* pszContentsMaxX,
685                                  const char* pszContentsMaxY,
686                                  char** papszOpenOptions,
687                                  OGRDB2Statement* oStmt,
688                                  int nIdxInResult );
689     int             InitRaster ( OGRDB2DataSource* poParentDS,
690                                  const char* pszTableName,
691                                  int nZoomLevel,
692                                  int nBandCount,
693                                  double dfTMSMinX,
694                                  double dfTMSMaxY,
695                                  double dfPixelXSize,
696                                  double dfPixelYSize,
697                                  int nTileWidth,
698                                  int nTileHeight,
699                                  int nTileMatrixWidth,
700                                  int nTileMatrixHeight,
701                                  double dfGDALMinX,
702                                  double dfGDALMinY,
703                                  double dfGDALMaxX,
704                                  double dfGDALMaxY );
705 
706     int     OpenRaster( const char* pszTableName,
707                         const char* pszIdentifier,
708                         const char* pszDescription,
709                         int nSRSId,
710                         double dfMinX,
711                         double dfMinY,
712                         double dfMaxX,
713                         double dfMaxY,
714                         const char* pszContentsMinX,
715                         const char* pszContentsMinY,
716                         const char* pszContentsMaxX,
717                         const char* pszContentsMaxY,
718                         char** papszOptions );
719     CPLErr   FinalizeRasterRegistration();
720 
721     CPLErr                  ReadTile(const CPLString& osMemFileName,
722                                      GByte* pabyTileData,
723                                      int* pbIsLossyFormat = nullptr);
724     GByte*                  ReadTile(int nRow, int nCol);
725     GByte*                  ReadTile(int nRow, int nCol, GByte* pabyData,
726                                      int* pbIsLossyFormat = nullptr);
727 
728     int                     m_bInWriteTile;
729     CPLErr                  WriteTile();
730 
731     CPLErr                  WriteTileInternal();
732     // cppcheck-suppress functionStatic
733     CPLErr                  FlushRemainingShiftedTiles();
734     // cppcheck-suppress functionStatic
735     CPLErr                  WriteShiftedTile(int nRow, int nCol, int iBand,
736             int nDstXOffset, int nDstYOffset,
737             int nDstXSize, int nDstYSize);
738 
739     int                     RegisterWebPExtension();
740     int                     RegisterZoomOtherExtension();
741     void                    ParseCompressionOptions(char** papszOptions);
742 
743     int                     HasMetadataTables();
744     int                     CreateMetadataTables();
745     const char*             CheckMetadataDomain( const char* pszDomain );
746     void                    WriteMetadata(CPLXMLNode* psXMLNode,
747                                           const char* pszTableName);
748     CPLErr                  FlushMetadata();
749 
750 //***************** For raster support
751 
752 public:
753     OGRDB2DataSource();
754     virtual ~OGRDB2DataSource();
755 //***************** For raster support
756 
757     virtual char **     GetMetadata( const char *pszDomain = nullptr ) override;
758     virtual const char *GetMetadataItem( const char * pszName,
759                                          const char * pszDomain = "" ) override;
760     virtual char **     GetMetadataDomainList() override;
761     virtual CPLErr      SetMetadata( char ** papszMetadata,
762                                      const char * pszDomain = "" ) override;
763     virtual CPLErr      SetMetadataItem( const char * pszName,
764                                          const char * pszValue,
765                                          const char * pszDomain = "" ) override;
766     CPLErr              FlushCacheWithErrCode();
767 
768     virtual const char* _GetProjectionRef() override;
769     virtual CPLErr      _SetProjection( const char* pszProjection ) override;
GetSpatialRef()770     const OGRSpatialReference* GetSpatialRef() const override {
771         return GetSpatialRefFromOldGetProjectionRef();
772     }
SetSpatialRef(const OGRSpatialReference * poSRS)773     CPLErr SetSpatialRef(const OGRSpatialReference* poSRS) override {
774         return OldSetProjectionFromSetSpatialRef(poSRS);
775     }
776 
777     virtual CPLErr      GetGeoTransform( double* padfGeoTransform ) override;
778     virtual CPLErr      SetGeoTransform( double* padfGeoTransform ) override;
779 
780     virtual CPLErr      IBuildOverviews( const char *, int, int *,
781                                          int, int *,
782                                          GDALProgressFunc, void * ) override;
783 
784     OGRErr              CreateGDALAspatialExtension();
SetMetadataDirty()785     void                SetMetadataDirty() {
786         m_bMetadataDirty = TRUE;
787     }
788     /*
789     */
790     // cppcheck-suppress functionStatic
791     OGRErr              CreateExtensionsTableIfNecessary();
792     // cppcheck-suppress functionStatic
793     int                 HasExtensionsTable();
794     virtual void        FlushCache() override;
795     static GDALDataset* CreateCopy( const char *pszFilename,
796                                     GDALDataset *poSrcDS,
797                                     int bStrict,
798                                     char ** papszOptions,
799                                     GDALProgressFunc pfnProgress,
800                                     void * pProgressData );
801 //*****************
802 
803     int                 DeleteLayer( OGRDB2TableLayer * poLayer );
GetCatalog()804     const char          *GetCatalog() {
805         return m_pszCatalog;
806     }
807 
808     static int                 ParseValue(char** pszValue, char* pszSource,
809                                    const char* pszKey,
810                                    int nStart, int nNext, int nTerm,
811                                    int bRemove);
812 
813     int                 Open(GDALOpenInfo* poOpenInfo);
814     int                 Create( const char * pszFilename,
815                                 int nXSize,
816                                 int nYSize,
817                                 int nBands,
818                                 GDALDataType eDT,
819                                 char **papszOptions );
820     int                 Open( const char *, int bTestOpen );
821     int                 OpenTable( const char *pszSchemaName,
822                                    const char *pszTableName,
823                                    const char *pszGeomCol,
824                                    int nCoordDimension,
825                                    int nSRID, const char *pszSRText,
826                                    OGRwkbGeometryType eType);
827 
GetName()828     const char          *GetName() {
829         return m_pszName;
830     }
831     int                 GetLayerCount() override;
832     OGRLayer            *GetLayer( int ) override;
833     OGRLayer            *GetLayerByName( const char* pszLayerName ) override;
834 
UseGeometryColumns()835     int                 UseGeometryColumns() {
836         return bUseGeometryColumns;
837     }
838 
839     virtual int         DeleteLayer( int iLayer ) override;
840     virtual OGRLayer    *ICreateLayer( const char *,
841                                        OGRSpatialReference * = nullptr,
842                                        OGRwkbGeometryType = wkbUnknown,
843                                        char ** = nullptr ) override;
844 
845     int                 TestCapability( const char * ) override;
846 
847     virtual OGRLayer *  ExecuteSQL( const char *pszSQLCommand,
848                                     OGRGeometry *poSpatialFilter,
849                                     const char *pszDialect ) override;
850     // cppcheck-suppress functionStatic
851     virtual void        ReleaseResultSet( OGRLayer * poLayer ) override;
852 
853     char                *LaunderName( const char *pszSrcName );
854     char                *ToUpper( const char *pszSrcName );
855     // cppcheck-suppress functionStatic
856     OGRErr              InitializeMetadataTables();
857 
858     OGRSpatialReference* FetchSRS( int nId );
859     int                 FetchSRSId( OGRSpatialReference * poSRS );
860 
861     OGRErr              StartTransaction(CPL_UNUSED int bForce) override;
862     OGRErr              CommitTransaction() override;
863     OGRErr              RollbackTransaction() override;
864     OGRErr              SoftStartTransaction();
865     OGRErr              SoftCommitTransaction();
866     OGRErr              SoftRollbackTransaction();
867     // Internal use
GetSession()868     OGRDB2Session     *GetSession() {
869         return &m_oSession;
870     }
871     int                 InitializeSession( const char * pszNewName,
872                                            int bTestOpen );
873 };
874 
875 /************************************************************************/
876 /*                             OGRDB2Driver                             */
877 /************************************************************************/
878 
879 class OGRDB2Driver final: public GDALDriver
880 {
881 public:
882     ~OGRDB2Driver();
883 };
884 
885 /************************************************************************/
886 /*                        GDALDB2RasterBand                             */
887 /************************************************************************/
888 
889 class GDALDB2RasterBand final: public GDALPamRasterBand
890 {
891 public:
892 
893     GDALDB2RasterBand(OGRDB2DataSource* poDS,
894                       int nBand,
895                       int nTileWidth, int nTileHeight);
896 
897     virtual CPLErr          IReadBlock(int nBlockXOff, int nBlockYOff,
898                                        void* pData) override;
899     virtual CPLErr          IWriteBlock(int nBlockXOff, int nBlockYOff,
900                                         void* pData) override;
901     virtual CPLErr          FlushCache() override;
902 
903     virtual GDALColorTable* GetColorTable() override;
904     virtual CPLErr          SetColorTable(GDALColorTable* poCT) override;
905 
906     virtual GDALColorInterp GetColorInterpretation() override;
907     virtual CPLErr          SetColorInterpretation( GDALColorInterp ) override;
908 
909     virtual int             GetOverviewCount() override;
910     virtual GDALRasterBand* GetOverview(int nIdx) override;
911     char*           GByteArrayToHexString( const GByte* pabyData, int nLen);
912 };
913 #endif /* ndef OGR_DB2_H_INCLUDED */
914