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