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 : * Permission is hereby granted, free of charge, to any person obtaining a
14 : * copy of this software and associated documentation files (the "Software"),
15 : * to deal in the Software without restriction, including without limitation
16 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 : * and/or sell copies of the Software, and to permit persons to whom the
18 : * Software is furnished to do so, subject to the following conditions:
19 : *
20 : * The above copyright notice and this permission notice shall be included
21 : * in all copies or substantial portions of the Software.
22 : *
23 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 : * DEALINGS IN THE SOFTWARE.
30 : ****************************************************************************/
31 :
32 : #ifndef OGR_MYSQL_H_INCLUDED
33 : #define OGR_MYSQL_H_INCLUDED
34 :
35 : // Include cpl_port.h before mysql stuff to avoid issues with CPLIsFinite()
36 : // See https://trac.osgeo.org/gdal/ticket/6899
37 : #include "cpl_port.h"
38 :
39 : #ifdef _MSC_VER
40 : #pragma warning(push)
41 : // 'my_alignment_imp<0x02>' : structure was padded due to __declspec(align())
42 : #pragma warning(disable : 4324)
43 : // nonstandard extension used : nameless struct/union
44 : #pragma warning(disable : 4201)
45 : // nonstandard extension used : redefined extern to static
46 : #pragma warning(disable : 4211)
47 : // warning C4005: 'HAVE_STRUCT_TIMESPEC': macro redefinition
48 : #pragma warning(disable : 4005)
49 : #endif
50 :
51 : #include <mysql.h>
52 :
53 : #ifdef _MSC_VER
54 : #pragma warning(pop)
55 : #endif
56 :
57 : /* my_global.h from mysql 5.1 declares the min and max macros. */
58 : /* This conflicts with templates in g++-4.3.2 header files. Grrr */
59 : #ifdef min
60 : #undef min
61 : #endif
62 :
63 : #ifdef max
64 : #undef max
65 : #endif
66 :
67 : #ifdef bool
68 : #undef bool
69 : #endif
70 :
71 : #include "ogrsf_frmts.h"
72 :
73 : #include <map>
74 :
75 : class OGRMySQLDataSource;
76 :
77 : /************************************************************************/
78 : /* OGRMySQLGeomFieldDefn */
79 : /************************************************************************/
80 :
81 : class OGRMySQLGeomFieldDefn final : public OGRGeomFieldDefn
82 : {
83 : OGRMySQLGeomFieldDefn(const OGRMySQLGeomFieldDefn &) = delete;
84 : OGRMySQLGeomFieldDefn &operator=(const OGRMySQLGeomFieldDefn &) = delete;
85 :
86 : protected:
87 : OGRMySQLDataSource *poDS;
88 :
89 : public:
90 194 : OGRMySQLGeomFieldDefn(OGRMySQLDataSource *poDSIn, const char *pszFieldName)
91 194 : : OGRGeomFieldDefn(pszFieldName, wkbUnknown), poDS(poDSIn)
92 : {
93 194 : }
94 :
95 : virtual const OGRSpatialReference *GetSpatialRef() const override;
96 :
97 194 : void UnsetDataSource()
98 : {
99 194 : poDS = nullptr;
100 194 : }
101 :
102 : mutable int nSRSId = -1;
103 : };
104 :
105 : /************************************************************************/
106 : /* OGRMySQLLayer */
107 : /************************************************************************/
108 :
109 : class OGRMySQLLayer CPL_NON_FINAL : public OGRLayer
110 : {
111 : protected:
112 : OGRMySQLDataSource *poDS;
113 :
114 : OGRFeatureDefn *poFeatureDefn = nullptr;
115 :
116 : // Layer srid.
117 : int nSRSId = -2; // we haven't even queried the database for it yet.
118 :
119 : GIntBig iNextShapeId = 0;
120 :
121 : char *pszQueryStatement = nullptr;
122 :
123 : int nResultOffset = 0;
124 :
125 : char *pszGeomColumn = nullptr;
126 : char *pszGeomColumnTable = nullptr;
127 : int nGeomType = 0;
128 :
129 : int bHasFid = FALSE;
130 : char *pszFIDColumn = nullptr;
131 :
132 : MYSQL_RES *hResultSet = nullptr;
133 : bool m_bEOF = false;
134 :
135 : int FetchSRSId();
136 :
137 : public:
138 : explicit OGRMySQLLayer(OGRMySQLDataSource *poDSIn);
139 : virtual ~OGRMySQLLayer();
140 :
141 : virtual void ResetReading() override;
142 :
143 : virtual OGRFeature *GetNextFeature() override;
144 :
145 : virtual OGRFeature *GetFeature(GIntBig nFeatureId) override;
146 :
147 11009 : OGRFeatureDefn *GetLayerDefn() override
148 : {
149 11009 : return poFeatureDefn;
150 : }
151 :
152 : virtual const char *GetFIDColumn() override;
153 :
154 : /* custom methods */
155 : virtual OGRFeature *RecordToFeature(char **papszRow, unsigned long *);
156 : virtual OGRFeature *GetNextRawFeature();
157 :
158 : GDALDataset *GetDataset() override;
159 : };
160 :
161 : /************************************************************************/
162 : /* OGRMySQLTableLayer */
163 : /************************************************************************/
164 :
165 : class OGRMySQLTableLayer final : public OGRMySQLLayer
166 : {
167 : int bUpdateAccess;
168 :
169 : OGRFeatureDefn *ReadTableDefinition(const char *);
170 :
171 : void BuildWhere();
172 : char *BuildFields();
173 : void BuildFullQueryStatement();
174 :
175 : char *pszQuery;
176 : char *pszWHERE;
177 :
178 : int bLaunderColumnNames;
179 : int bPreservePrecision;
180 :
181 : public:
182 : OGRMySQLTableLayer(OGRMySQLDataSource *, const char *pszName, int bUpdate,
183 : int nSRSId = -2);
184 : virtual ~OGRMySQLTableLayer();
185 :
186 : OGRErr Initialize(const char *pszTableName);
187 :
188 : virtual OGRFeature *GetFeature(GIntBig nFeatureId) override;
189 : virtual void ResetReading() override;
190 : virtual GIntBig GetFeatureCount(int) override;
191 :
192 : void SetSpatialFilter(OGRGeometry *) override;
193 :
194 12 : virtual void SetSpatialFilter(int iGeomField, OGRGeometry *poGeom) override
195 : {
196 12 : OGRLayer::SetSpatialFilter(iGeomField, poGeom);
197 12 : }
198 :
199 : virtual OGRErr SetAttributeFilter(const char *) override;
200 : virtual OGRErr ICreateFeature(OGRFeature *poFeature) override;
201 : virtual OGRErr DeleteFeature(GIntBig nFID) override;
202 : virtual OGRErr ISetFeature(OGRFeature *poFeature) override;
203 :
204 : virtual OGRErr CreateField(const OGRFieldDefn *poField,
205 : int bApproxOK = TRUE) override;
206 :
207 176 : void SetLaunderFlag(int bFlag)
208 : {
209 176 : bLaunderColumnNames = bFlag;
210 176 : }
211 :
212 176 : void SetPrecisionFlag(int bFlag)
213 : {
214 176 : bPreservePrecision = bFlag;
215 176 : }
216 :
217 : virtual int TestCapability(const char *) override;
218 : virtual OGRErr GetExtent(OGREnvelope *psExtent, int bForce = TRUE) override;
219 :
220 12 : virtual OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent,
221 : int bForce) override
222 : {
223 12 : return OGRLayer::GetExtent(iGeomField, psExtent, bForce);
224 : }
225 : };
226 :
227 : /************************************************************************/
228 : /* OGRMySQLResultLayer */
229 : /************************************************************************/
230 :
231 : class OGRMySQLResultLayer final : public OGRMySQLLayer
232 : {
233 : void BuildFullQueryStatement();
234 :
235 : char *pszRawStatement;
236 :
237 : public:
238 : OGRMySQLResultLayer(OGRMySQLDataSource *, const char *pszRawStatement,
239 : MYSQL_RES *hResultSetIn);
240 : virtual ~OGRMySQLResultLayer();
241 :
242 : OGRFeatureDefn *ReadResultDefinition();
243 :
244 : virtual void ResetReading() override;
245 : virtual GIntBig GetFeatureCount(int) override;
246 :
247 : virtual int TestCapability(const char *) override;
248 : };
249 :
250 : /************************************************************************/
251 : /* OGRMySQLDataSource */
252 : /************************************************************************/
253 :
254 : class OGRMySQLDataSource final : public OGRDataSource
255 : {
256 : OGRMySQLLayer **papoLayers;
257 : int nLayers;
258 :
259 : char *pszName;
260 :
261 : int bDSUpdate;
262 :
263 : MYSQL *hConn;
264 :
265 : OGRErr DeleteLayer(int iLayer) override;
266 :
267 : // We maintain a list of known SRID to reduce the number of trips to
268 : // the database to get SRSes.
269 : std::map<int,
270 : std::unique_ptr<OGRSpatialReference, OGRSpatialReferenceReleaser>>
271 : m_oSRSCache{};
272 :
273 : OGRMySQLLayer *poLongResultLayer;
274 :
275 : bool m_bIsMariaDB = false;
276 : int m_nMajor = 0;
277 : int m_nMinor = 0;
278 :
279 : public:
280 : OGRMySQLDataSource();
281 : virtual ~OGRMySQLDataSource();
282 :
283 5609 : MYSQL *GetConn()
284 : {
285 5609 : return hConn;
286 : }
287 :
288 : int FetchSRSId(const OGRSpatialReference *poSRS);
289 :
290 : const OGRSpatialReference *FetchSRS(int nSRSId);
291 :
292 : OGRErr InitializeMetadataTables();
293 : OGRErr UpdateMetadataTables(const char *pszLayerName,
294 : OGRwkbGeometryType eType,
295 : const char *pszGeomColumnName,
296 : const int nSRSId);
297 :
298 : int Open(const char *, char **papszOpenOptions, int bUpdate);
299 : int OpenTable(const char *, int bUpdate);
300 :
301 0 : const char *GetName() override
302 : {
303 0 : return pszName;
304 : }
305 :
306 3995 : int GetLayerCount() override
307 : {
308 3995 : return nLayers;
309 : }
310 :
311 : OGRLayer *GetLayer(int) override;
312 :
313 : OGRLayer *ICreateLayer(const char *pszName,
314 : const OGRGeomFieldDefn *poGeomFieldDefn,
315 : CSLConstList papszOptions) override;
316 :
317 : int TestCapability(const char *) override;
318 :
319 : virtual OGRLayer *ExecuteSQL(const char *pszSQLCommand,
320 : OGRGeometry *poSpatialFilter,
321 : const char *pszDialect) override;
322 : virtual void ReleaseResultSet(OGRLayer *poLayer) override;
323 :
324 : // nonstandard
325 :
326 : void ReportError(const char * = nullptr);
327 :
328 : static char *LaunderName(const char *);
329 :
330 : void RequestLongResult(OGRMySQLLayer *);
331 : void InterruptLongResult();
332 :
333 1875 : bool IsMariaDB() const
334 : {
335 1875 : return m_bIsMariaDB;
336 : }
337 :
338 2329 : int GetMajorVersion() const
339 : {
340 2329 : return m_nMajor;
341 : }
342 :
343 : int GetUnknownSRID() const;
344 : };
345 :
346 : std::string OGRMySQLEscapeLiteral(const char *pszLiteral);
347 :
348 : #endif /* ndef OGR_MYSQL_H_INCLUDED */
|