Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: OpenGIS Simple Features Reference Implementation 4 : * Purpose: Declarations for MySQL OGR Driver Classes. 5 : * Author: Frank Warmerdam, warmerdam@pobox.com 6 : * Author: Howard Butler, hobu@hobu.net 7 : * 8 : ****************************************************************************** 9 : * Copyright (c) 2004, Frank Warmerdam <warmerdam@pobox.com> 10 : * Copyright (c) 2008-2012, Even Rouault <even dot rouault at spatialys.com> 11 : * 12 : * SPDX-License-Identifier: MIT 13 : ****************************************************************************/ 14 : 15 : #ifndef OGR_MYSQL_H_INCLUDED 16 : #define OGR_MYSQL_H_INCLUDED 17 : 18 : // Include cpl_port.h before mysql stuff to avoid issues with CPLIsFinite() 19 : // See https://trac.osgeo.org/gdal/ticket/6899 20 : #include "cpl_port.h" 21 : 22 : #ifdef _MSC_VER 23 : #pragma warning(push) 24 : // 'my_alignment_imp<0x02>' : structure was padded due to __declspec(align()) 25 : #pragma warning(disable : 4324) 26 : // nonstandard extension used : nameless struct/union 27 : #pragma warning(disable : 4201) 28 : // nonstandard extension used : redefined extern to static 29 : #pragma warning(disable : 4211) 30 : // warning C4005: 'HAVE_STRUCT_TIMESPEC': macro redefinition 31 : #pragma warning(disable : 4005) 32 : #endif 33 : 34 : #include <mysql.h> 35 : 36 : #ifdef _MSC_VER 37 : #pragma warning(pop) 38 : #endif 39 : 40 : /* my_global.h from mysql 5.1 declares the min and max macros. */ 41 : /* This conflicts with templates in g++-4.3.2 header files. Grrr */ 42 : #ifdef min 43 : #undef min 44 : #endif 45 : 46 : #ifdef max 47 : #undef max 48 : #endif 49 : 50 : #ifdef bool 51 : #undef bool 52 : #endif 53 : 54 : #include "ogrsf_frmts.h" 55 : 56 : #include <map> 57 : 58 : class OGRMySQLDataSource; 59 : 60 : /************************************************************************/ 61 : /* OGRMySQLGeomFieldDefn */ 62 : /************************************************************************/ 63 : 64 : class OGRMySQLGeomFieldDefn final : public OGRGeomFieldDefn 65 : { 66 : OGRMySQLGeomFieldDefn(const OGRMySQLGeomFieldDefn &) = delete; 67 : OGRMySQLGeomFieldDefn &operator=(const OGRMySQLGeomFieldDefn &) = delete; 68 : 69 : protected: 70 : OGRMySQLDataSource *poDS; 71 : 72 : public: 73 194 : OGRMySQLGeomFieldDefn(OGRMySQLDataSource *poDSIn, const char *pszFieldName) 74 194 : : OGRGeomFieldDefn(pszFieldName, wkbUnknown), poDS(poDSIn) 75 : { 76 194 : } 77 : 78 : virtual const OGRSpatialReference *GetSpatialRef() const override; 79 : 80 194 : void UnsetDataSource() 81 : { 82 194 : poDS = nullptr; 83 194 : } 84 : 85 : mutable int nSRSId = -1; 86 : }; 87 : 88 : /************************************************************************/ 89 : /* OGRMySQLLayer */ 90 : /************************************************************************/ 91 : 92 : class OGRMySQLLayer CPL_NON_FINAL : public OGRLayer 93 : { 94 : protected: 95 : OGRMySQLDataSource *poDS; 96 : 97 : OGRFeatureDefn *poFeatureDefn = nullptr; 98 : 99 : // Layer srid. 100 : int nSRSId = -2; // we haven't even queried the database for it yet. 101 : 102 : GIntBig iNextShapeId = 0; 103 : 104 : char *pszQueryStatement = nullptr; 105 : 106 : int nResultOffset = 0; 107 : 108 : char *pszGeomColumn = nullptr; 109 : char *pszGeomColumnTable = nullptr; 110 : int nGeomType = 0; 111 : 112 : int bHasFid = FALSE; 113 : char *pszFIDColumn = nullptr; 114 : 115 : MYSQL_RES *hResultSet = nullptr; 116 : bool m_bEOF = false; 117 : 118 : int FetchSRSId(); 119 : 120 : public: 121 : explicit OGRMySQLLayer(OGRMySQLDataSource *poDSIn); 122 : virtual ~OGRMySQLLayer(); 123 : 124 : virtual void ResetReading() override; 125 : 126 : virtual OGRFeature *GetNextFeature() override; 127 : 128 : virtual OGRFeature *GetFeature(GIntBig nFeatureId) override; 129 : 130 11115 : OGRFeatureDefn *GetLayerDefn() override 131 : { 132 11115 : return poFeatureDefn; 133 : } 134 : 135 : virtual const char *GetFIDColumn() override; 136 : 137 : /* custom methods */ 138 : virtual OGRFeature *RecordToFeature(char **papszRow, unsigned long *); 139 : virtual OGRFeature *GetNextRawFeature(); 140 : 141 : GDALDataset *GetDataset() override; 142 : }; 143 : 144 : /************************************************************************/ 145 : /* OGRMySQLTableLayer */ 146 : /************************************************************************/ 147 : 148 : class OGRMySQLTableLayer final : public OGRMySQLLayer 149 : { 150 : int bUpdateAccess; 151 : 152 : OGRFeatureDefn *ReadTableDefinition(const char *); 153 : 154 : void BuildWhere(); 155 : char *BuildFields(); 156 : void BuildFullQueryStatement(); 157 : 158 : char *pszQuery; 159 : char *pszWHERE; 160 : 161 : int bLaunderColumnNames; 162 : int bPreservePrecision; 163 : 164 : public: 165 : OGRMySQLTableLayer(OGRMySQLDataSource *, const char *pszName, int bUpdate, 166 : int nSRSId = -2); 167 : virtual ~OGRMySQLTableLayer(); 168 : 169 : OGRErr Initialize(const char *pszTableName); 170 : 171 : virtual OGRFeature *GetFeature(GIntBig nFeatureId) override; 172 : virtual void ResetReading() override; 173 : virtual GIntBig GetFeatureCount(int) override; 174 : 175 : OGRErr ISetSpatialFilter(int iGeomField, 176 : const OGRGeometry *poGeom) override; 177 : 178 : virtual OGRErr SetAttributeFilter(const char *) override; 179 : virtual OGRErr ICreateFeature(OGRFeature *poFeature) override; 180 : virtual OGRErr DeleteFeature(GIntBig nFID) override; 181 : virtual OGRErr ISetFeature(OGRFeature *poFeature) override; 182 : 183 : virtual OGRErr CreateField(const OGRFieldDefn *poField, 184 : int bApproxOK = TRUE) override; 185 : 186 176 : void SetLaunderFlag(int bFlag) 187 : { 188 176 : bLaunderColumnNames = bFlag; 189 176 : } 190 : 191 176 : void SetPrecisionFlag(int bFlag) 192 : { 193 176 : bPreservePrecision = bFlag; 194 176 : } 195 : 196 : virtual int TestCapability(const char *) override; 197 : 198 : OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent, 199 : bool bForce) override; 200 : }; 201 : 202 : /************************************************************************/ 203 : /* OGRMySQLResultLayer */ 204 : /************************************************************************/ 205 : 206 : class OGRMySQLResultLayer final : public OGRMySQLLayer 207 : { 208 : void BuildFullQueryStatement(); 209 : 210 : char *pszRawStatement; 211 : 212 : public: 213 : OGRMySQLResultLayer(OGRMySQLDataSource *, const char *pszRawStatement, 214 : MYSQL_RES *hResultSetIn); 215 : virtual ~OGRMySQLResultLayer(); 216 : 217 : OGRFeatureDefn *ReadResultDefinition(); 218 : 219 : virtual void ResetReading() override; 220 : virtual GIntBig GetFeatureCount(int) override; 221 : 222 : virtual int TestCapability(const char *) override; 223 : }; 224 : 225 : /************************************************************************/ 226 : /* OGRMySQLDataSource */ 227 : /************************************************************************/ 228 : 229 : class OGRMySQLDataSource final : public GDALDataset 230 : { 231 : OGRMySQLLayer **papoLayers; 232 : int nLayers; 233 : 234 : int bDSUpdate; 235 : 236 : MYSQL *hConn; 237 : 238 : OGRErr DeleteLayer(int iLayer) override; 239 : 240 : // We maintain a list of known SRID to reduce the number of trips to 241 : // the database to get SRSes. 242 : std::map<int, 243 : std::unique_ptr<OGRSpatialReference, OGRSpatialReferenceReleaser>> 244 : m_oSRSCache{}; 245 : 246 : OGRMySQLLayer *poLongResultLayer; 247 : 248 : bool m_bIsMariaDB = false; 249 : int m_nMajor = 0; 250 : int m_nMinor = 0; 251 : 252 : public: 253 : OGRMySQLDataSource(); 254 : virtual ~OGRMySQLDataSource(); 255 : 256 5669 : MYSQL *GetConn() 257 : { 258 5669 : return hConn; 259 : } 260 : 261 : int FetchSRSId(const OGRSpatialReference *poSRS); 262 : 263 : const OGRSpatialReference *FetchSRS(int nSRSId); 264 : 265 : OGRErr InitializeMetadataTables(); 266 : OGRErr UpdateMetadataTables(const char *pszLayerName, 267 : OGRwkbGeometryType eType, 268 : const char *pszGeomColumnName, 269 : const int nSRSId); 270 : 271 : int Open(const char *, char **papszOpenOptions, int bUpdate); 272 : int OpenTable(const char *, int bUpdate); 273 : 274 3995 : int GetLayerCount() override 275 : { 276 3995 : return nLayers; 277 : } 278 : 279 : OGRLayer *GetLayer(int) override; 280 : 281 : OGRLayer *ICreateLayer(const char *pszName, 282 : const OGRGeomFieldDefn *poGeomFieldDefn, 283 : CSLConstList papszOptions) override; 284 : 285 : int TestCapability(const char *) override; 286 : 287 : virtual OGRLayer *ExecuteSQL(const char *pszSQLCommand, 288 : OGRGeometry *poSpatialFilter, 289 : const char *pszDialect) override; 290 : virtual void ReleaseResultSet(OGRLayer *poLayer) override; 291 : 292 : // nonstandard 293 : 294 : void ReportError(const char * = nullptr); 295 : 296 : static char *LaunderName(const char *); 297 : 298 : void RequestLongResult(OGRMySQLLayer *); 299 : void InterruptLongResult(); 300 : 301 1879 : bool IsMariaDB() const 302 : { 303 1879 : return m_bIsMariaDB; 304 : } 305 : 306 2337 : int GetMajorVersion() const 307 : { 308 2337 : return m_nMajor; 309 : } 310 : 311 : int GetUnknownSRID() const; 312 : }; 313 : 314 : std::string OGRMySQLEscapeLiteral(const char *pszLiteral); 315 : 316 : #endif /* ndef OGR_MYSQL_H_INCLUDED */