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 11083 : OGRFeatureDefn *GetLayerDefn() override 131 : { 132 11083 : 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 : void SetSpatialFilter(OGRGeometry *) override; 176 : 177 12 : virtual void SetSpatialFilter(int iGeomField, OGRGeometry *poGeom) override 178 : { 179 12 : OGRLayer::SetSpatialFilter(iGeomField, poGeom); 180 12 : } 181 : 182 : virtual OGRErr SetAttributeFilter(const char *) override; 183 : virtual OGRErr ICreateFeature(OGRFeature *poFeature) override; 184 : virtual OGRErr DeleteFeature(GIntBig nFID) override; 185 : virtual OGRErr ISetFeature(OGRFeature *poFeature) override; 186 : 187 : virtual OGRErr CreateField(const OGRFieldDefn *poField, 188 : int bApproxOK = TRUE) override; 189 : 190 176 : void SetLaunderFlag(int bFlag) 191 : { 192 176 : bLaunderColumnNames = bFlag; 193 176 : } 194 : 195 176 : void SetPrecisionFlag(int bFlag) 196 : { 197 176 : bPreservePrecision = bFlag; 198 176 : } 199 : 200 : virtual int TestCapability(const char *) override; 201 : virtual OGRErr GetExtent(OGREnvelope *psExtent, int bForce = TRUE) override; 202 : 203 12 : virtual OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent, 204 : int bForce) override 205 : { 206 12 : return OGRLayer::GetExtent(iGeomField, psExtent, bForce); 207 : } 208 : }; 209 : 210 : /************************************************************************/ 211 : /* OGRMySQLResultLayer */ 212 : /************************************************************************/ 213 : 214 : class OGRMySQLResultLayer final : public OGRMySQLLayer 215 : { 216 : void BuildFullQueryStatement(); 217 : 218 : char *pszRawStatement; 219 : 220 : public: 221 : OGRMySQLResultLayer(OGRMySQLDataSource *, const char *pszRawStatement, 222 : MYSQL_RES *hResultSetIn); 223 : virtual ~OGRMySQLResultLayer(); 224 : 225 : OGRFeatureDefn *ReadResultDefinition(); 226 : 227 : virtual void ResetReading() override; 228 : virtual GIntBig GetFeatureCount(int) override; 229 : 230 : virtual int TestCapability(const char *) override; 231 : }; 232 : 233 : /************************************************************************/ 234 : /* OGRMySQLDataSource */ 235 : /************************************************************************/ 236 : 237 : class OGRMySQLDataSource final : public GDALDataset 238 : { 239 : OGRMySQLLayer **papoLayers; 240 : int nLayers; 241 : 242 : int bDSUpdate; 243 : 244 : MYSQL *hConn; 245 : 246 : OGRErr DeleteLayer(int iLayer) override; 247 : 248 : // We maintain a list of known SRID to reduce the number of trips to 249 : // the database to get SRSes. 250 : std::map<int, 251 : std::unique_ptr<OGRSpatialReference, OGRSpatialReferenceReleaser>> 252 : m_oSRSCache{}; 253 : 254 : OGRMySQLLayer *poLongResultLayer; 255 : 256 : bool m_bIsMariaDB = false; 257 : int m_nMajor = 0; 258 : int m_nMinor = 0; 259 : 260 : public: 261 : OGRMySQLDataSource(); 262 : virtual ~OGRMySQLDataSource(); 263 : 264 5669 : MYSQL *GetConn() 265 : { 266 5669 : return hConn; 267 : } 268 : 269 : int FetchSRSId(const OGRSpatialReference *poSRS); 270 : 271 : const OGRSpatialReference *FetchSRS(int nSRSId); 272 : 273 : OGRErr InitializeMetadataTables(); 274 : OGRErr UpdateMetadataTables(const char *pszLayerName, 275 : OGRwkbGeometryType eType, 276 : const char *pszGeomColumnName, 277 : const int nSRSId); 278 : 279 : int Open(const char *, char **papszOpenOptions, int bUpdate); 280 : int OpenTable(const char *, int bUpdate); 281 : 282 3995 : int GetLayerCount() override 283 : { 284 3995 : return nLayers; 285 : } 286 : 287 : OGRLayer *GetLayer(int) override; 288 : 289 : OGRLayer *ICreateLayer(const char *pszName, 290 : const OGRGeomFieldDefn *poGeomFieldDefn, 291 : CSLConstList papszOptions) override; 292 : 293 : int TestCapability(const char *) override; 294 : 295 : virtual OGRLayer *ExecuteSQL(const char *pszSQLCommand, 296 : OGRGeometry *poSpatialFilter, 297 : const char *pszDialect) override; 298 : virtual void ReleaseResultSet(OGRLayer *poLayer) override; 299 : 300 : // nonstandard 301 : 302 : void ReportError(const char * = nullptr); 303 : 304 : static char *LaunderName(const char *); 305 : 306 : void RequestLongResult(OGRMySQLLayer *); 307 : void InterruptLongResult(); 308 : 309 1879 : bool IsMariaDB() const 310 : { 311 1879 : return m_bIsMariaDB; 312 : } 313 : 314 2337 : int GetMajorVersion() const 315 : { 316 2337 : return m_nMajor; 317 : } 318 : 319 : int GetUnknownSRID() const; 320 : }; 321 : 322 : std::string OGRMySQLEscapeLiteral(const char *pszLiteral); 323 : 324 : #endif /* ndef OGR_MYSQL_H_INCLUDED */