/src/gdal/ogr/ogrsf_frmts/adbc/ogr_adbc.h
Line | Count | Source |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Project: GDAL |
4 | | * Purpose: Arrow Database Connectivity driver |
5 | | * Author: Even Rouault, <even dot rouault at spatialys.com> |
6 | | * |
7 | | ****************************************************************************** |
8 | | * Copyright (c) 2024, Even Rouault <even dot rouault at spatialys.com> |
9 | | * |
10 | | * SPDX-License-Identifier: MIT |
11 | | ****************************************************************************/ |
12 | | |
13 | | #ifndef OGR_ADBC_INCLUDED |
14 | | #define OGR_ADBC_INCLUDED |
15 | | |
16 | | #include "gdal_priv.h" |
17 | | #include "ogrsf_frmts.h" |
18 | | #include "ogrlayerarrow.h" |
19 | | |
20 | | #include "ogr_adbc_internal.h" |
21 | | |
22 | | /************************************************************************/ |
23 | | /* OGRArrowArrayToOGRFeatureAdapterLayer */ |
24 | | /************************************************************************/ |
25 | | |
26 | | class OGRArrowArrayToOGRFeatureAdapterLayer final : public OGRLayer |
27 | | { |
28 | | friend class OGRADBCLayer; |
29 | | OGRFeatureDefn *m_poLayerDefn = nullptr; |
30 | | std::vector<std::unique_ptr<OGRFeature>> m_apoFeatures{}; |
31 | | |
32 | | CPL_DISALLOW_COPY_ASSIGN(OGRArrowArrayToOGRFeatureAdapterLayer) |
33 | | |
34 | | public: |
35 | | explicit OGRArrowArrayToOGRFeatureAdapterLayer(const char *pszName) |
36 | 0 | { |
37 | 0 | m_poLayerDefn = new OGRFeatureDefn(pszName); |
38 | 0 | m_poLayerDefn->SetGeomType(wkbNone); |
39 | 0 | m_poLayerDefn->Reference(); |
40 | 0 | } |
41 | | |
42 | | ~OGRArrowArrayToOGRFeatureAdapterLayer() override; |
43 | | |
44 | | using OGRLayer::GetLayerDefn; |
45 | | |
46 | | const OGRFeatureDefn *GetLayerDefn() const override |
47 | 0 | { |
48 | 0 | return m_poLayerDefn; |
49 | 0 | } |
50 | | |
51 | | void ResetReading() override |
52 | 0 | { |
53 | 0 | } |
54 | | |
55 | | OGRFeature *GetNextFeature() override |
56 | 0 | { |
57 | 0 | return nullptr; |
58 | 0 | } |
59 | | |
60 | | int TestCapability(const char *pszCap) const override |
61 | 0 | { |
62 | 0 | return EQUAL(pszCap, OLCCreateField) || |
63 | 0 | EQUAL(pszCap, OLCSequentialWrite); |
64 | 0 | } |
65 | | |
66 | | OGRErr CreateField(const OGRFieldDefn *poFieldDefn, int) override |
67 | 0 | { |
68 | 0 | m_poLayerDefn->AddFieldDefn(poFieldDefn); |
69 | 0 | return OGRERR_NONE; |
70 | 0 | } |
71 | | |
72 | | OGRErr CreateGeomField(const OGRGeomFieldDefn *poGeomFieldDefn, |
73 | | int) override |
74 | 0 | { |
75 | 0 | m_poLayerDefn->AddGeomFieldDefn(poGeomFieldDefn); |
76 | 0 | return OGRERR_NONE; |
77 | 0 | } |
78 | | |
79 | | OGRErr ICreateFeature(OGRFeature *poFeature) override |
80 | 0 | { |
81 | 0 | m_apoFeatures.emplace_back( |
82 | 0 | std::unique_ptr<OGRFeature>(poFeature->Clone())); |
83 | 0 | return OGRERR_NONE; |
84 | 0 | } |
85 | | }; |
86 | | |
87 | | /************************************************************************/ |
88 | | /* OGRADBCLayer */ |
89 | | /************************************************************************/ |
90 | | |
91 | | class OGRADBCDataset; |
92 | | |
93 | | class OGRADBCLayer /* non final */ : public OGRLayer, |
94 | | public OGRGetNextFeatureThroughRaw< |
95 | | OGRADBCLayer> |
96 | | { |
97 | | public: |
98 | | //! Describe the bbox column of a geometry column |
99 | | struct GeomColBBOX |
100 | | { |
101 | | std::string osXMin{}; // empty if no bbox column |
102 | | std::string osYMin{}; |
103 | | std::string osXMax{}; |
104 | | std::string osYMax{}; |
105 | | }; |
106 | | |
107 | | protected: |
108 | | friend class OGRADBCDataset; |
109 | | |
110 | | OGRADBCDataset *m_poDS = nullptr; |
111 | | const std::string m_osBaseStatement{}; // as provided by user |
112 | | std::string m_osModifiedBaseStatement{}; // above tuned to use ST_AsWKB() |
113 | | std::string m_osModifiedSelect{}; // SELECT part of above |
114 | | std::string m_osAttributeFilter{}; |
115 | | std::unique_ptr<AdbcStatement> m_statement{}; |
116 | | std::unique_ptr<OGRArrowArrayToOGRFeatureAdapterLayer> m_poAdapterLayer{}; |
117 | | std::unique_ptr<OGRArrowArrayStream> m_stream{}; |
118 | | bool m_bInternalUse = false; |
119 | | bool m_bLayerDefinitionError = false; |
120 | | |
121 | | struct ArrowSchema m_schema{}; |
122 | | |
123 | | bool m_bEOF = false; |
124 | | size_t m_nIdx = 0; |
125 | | GIntBig m_nFeatureID = 0; |
126 | | GIntBig m_nMaxFeatureID = -1; |
127 | | bool m_bIsParquetLayer = false; |
128 | | |
129 | | std::vector<GeomColBBOX> |
130 | | m_geomColBBOX{}; // same size as GetGeomFieldCount() |
131 | | std::vector<OGREnvelope3D> m_extents{}; // same size as GetGeomFieldCount() |
132 | | std::string m_osFIDColName{}; |
133 | | |
134 | | OGRFeature *GetNextRawFeature(); |
135 | | bool GetArrowStreamInternal(struct ArrowArrayStream *out_stream); |
136 | | GIntBig GetFeatureCountSelectCountStar(); |
137 | | GIntBig GetFeatureCountArrow(); |
138 | | GIntBig GetFeatureCountParquet(); |
139 | | |
140 | | bool BuildLayerDefnInit(); |
141 | | virtual void BuildLayerDefn(); |
142 | | bool ReplaceStatement(const char *pszNewStatement); |
143 | | bool UpdateStatement(); |
144 | | virtual std::string GetCurrentStatement() const; |
145 | | |
146 | | virtual bool RunDeferredCreation() |
147 | 0 | { |
148 | 0 | return true; |
149 | 0 | } |
150 | | |
151 | | CPL_DISALLOW_COPY_ASSIGN(OGRADBCLayer) |
152 | | |
153 | | public: |
154 | | OGRADBCLayer(OGRADBCDataset *poDS, const char *pszName, |
155 | | const std::string &osStatement, bool bInternalUse); |
156 | | OGRADBCLayer(OGRADBCDataset *poDS, const char *pszName, |
157 | | std::unique_ptr<OGRArrowArrayStream> poStream, |
158 | | ArrowSchema *schema, bool bInternalUse); |
159 | | ~OGRADBCLayer() override; |
160 | | |
161 | | bool GotError(); |
162 | | |
163 | | using OGRLayer::GetLayerDefn; |
164 | | const OGRFeatureDefn *GetLayerDefn() const override; |
165 | | |
166 | | const char *GetName() const override |
167 | 0 | { |
168 | 0 | return GetDescription(); |
169 | 0 | } |
170 | | |
171 | | void ResetReading() override; |
172 | | DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(OGRADBCLayer) |
173 | | int TestCapability(const char *) const override; |
174 | | GDALDataset *GetDataset() override; |
175 | | bool GetArrowStream(struct ArrowArrayStream *out_stream, |
176 | | CSLConstList papszOptions = nullptr) override; |
177 | | GIntBig GetFeatureCount(int bForce) override; |
178 | | |
179 | | OGRErr SetAttributeFilter(const char *pszFilter) override; |
180 | | OGRErr ISetSpatialFilter(int iGeomField, |
181 | | const OGRGeometry *poGeom) override; |
182 | | |
183 | | OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent, |
184 | | bool bForce) override; |
185 | | OGRErr IGetExtent3D(int iGeomField, OGREnvelope3D *psExtent, |
186 | | bool bForce) override; |
187 | | |
188 | | const char *GetFIDColumn() const override; |
189 | | }; |
190 | | |
191 | | /************************************************************************/ |
192 | | /* OGRADBCBigQueryLayer */ |
193 | | /************************************************************************/ |
194 | | |
195 | | class OGRADBCBigQueryLayer final : public OGRADBCLayer |
196 | | { |
197 | | private: |
198 | | friend class OGRADBCDataset; |
199 | | |
200 | | bool m_bDeferredCreation = false; |
201 | | |
202 | | void BuildLayerDefn() override; |
203 | | bool RunDeferredCreation() override; |
204 | | std::string GetCurrentStatement() const override; |
205 | | bool GetBigQueryDatasetAndTableId(std::string &osDatasetId, |
206 | | std::string &osTableId) const; |
207 | | |
208 | | public: |
209 | | OGRADBCBigQueryLayer(OGRADBCDataset *poDS, const char *pszName, |
210 | | const std::string &osStatement, bool bInternalUse); |
211 | | |
212 | | int TestCapability(const char *) const override; |
213 | | GIntBig GetFeatureCount(int bForce) override; |
214 | | OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent, |
215 | | bool bForce) override; |
216 | | OGRErr SetAttributeFilter(const char *pszFilter) override; |
217 | | |
218 | | OGRErr CreateField(const OGRFieldDefn *poField, int bApproxOK) override; |
219 | | OGRErr ICreateFeature(OGRFeature *poFeature) override; |
220 | | OGRErr ISetFeature(OGRFeature *poFeature) override; |
221 | | OGRErr DeleteFeature(GIntBig nFID) override; |
222 | | |
223 | | void SetDeferredCreation(const char *pszFIDColName, |
224 | | const OGRGeomFieldDefn *poGeomFieldDefn); |
225 | | }; |
226 | | |
227 | | /************************************************************************/ |
228 | | /* OGRADBCDataset */ |
229 | | /************************************************************************/ |
230 | | |
231 | | class OGRADBCDataset final : public GDALDataset |
232 | | { |
233 | | friend class OGRADBCLayer; |
234 | | |
235 | | AdbcDriver m_driver{}; |
236 | | AdbcDatabase m_database{}; |
237 | | std::unique_ptr<AdbcConnection> m_connection{}; |
238 | | std::vector<std::unique_ptr<OGRLayer>> m_apoLayers{}; |
239 | | std::string m_osParquetFilename{}; |
240 | | bool m_bIsDuckDBDataset = false; |
241 | | bool m_bIsDuckDBDriver = false; |
242 | | bool m_bSpatialLoaded = false; |
243 | | bool m_bIsBigQuery = false; |
244 | | std::string m_osBigQueryDatasetId{}; |
245 | | |
246 | | public: |
247 | 25 | OGRADBCDataset() = default; |
248 | | ~OGRADBCDataset() override; |
249 | | |
250 | | CPLErr FlushCache(bool bAtClosing) override; |
251 | | |
252 | | bool Open(const GDALOpenInfo *poOpenInfo); |
253 | | |
254 | | int GetLayerCount() const override |
255 | 0 | { |
256 | 0 | return static_cast<int>(m_apoLayers.size()); |
257 | 0 | } |
258 | | |
259 | | const OGRLayer *GetLayer(int idx) const override |
260 | 0 | { |
261 | 0 | return (idx >= 0 && idx < GetLayerCount()) ? m_apoLayers[idx].get() |
262 | 0 | : nullptr; |
263 | 0 | } |
264 | | |
265 | | OGRLayer *GetLayerByName(const char *pszName) override; |
266 | | |
267 | | std::unique_ptr<OGRADBCLayer> CreateLayer(const char *pszStatement, |
268 | | const char *pszLayerName, |
269 | | bool bInternalUse); |
270 | | |
271 | | std::unique_ptr<OGRADBCLayer> |
272 | | CreateInternalLayer(const char *pszStatement) CPL_WARN_UNUSED_RESULT; |
273 | | |
274 | | OGRLayer *ICreateLayer(const char *pszName, |
275 | | const OGRGeomFieldDefn *poGeomFieldDefn, |
276 | | CSLConstList papszOptions) override; |
277 | | OGRErr DeleteLayer(int iLayer) override; |
278 | | |
279 | | OGRLayer *ExecuteSQL(const char *pszStatement, OGRGeometry *poSpatialFilter, |
280 | | const char *pszDialect) override; |
281 | | |
282 | | int TestCapability(const char *pszCap) const override; |
283 | | }; |
284 | | |
285 | | /************************************************************************/ |
286 | | /* OGRADBCError */ |
287 | | /************************************************************************/ |
288 | | |
289 | | struct OGRADBCError |
290 | | { |
291 | | AdbcError error{ADBC_ERROR_INIT}; |
292 | | |
293 | 50 | inline OGRADBCError() = default; |
294 | | |
295 | | inline ~OGRADBCError() |
296 | 50 | { |
297 | 50 | clear(); |
298 | 50 | } |
299 | | |
300 | | inline void clear() |
301 | 75 | { |
302 | 75 | if (error.release) |
303 | 0 | error.release(&error); |
304 | 75 | memset(&error, 0, sizeof(error)); |
305 | 75 | } |
306 | | |
307 | | inline const char *message() const |
308 | 0 | { |
309 | 0 | return error.message ? error.message : ""; |
310 | 0 | } |
311 | | |
312 | | inline operator AdbcError *() |
313 | 0 | { |
314 | 0 | return &error; |
315 | 0 | } |
316 | | |
317 | | CPL_DISALLOW_COPY_ASSIGN(OGRADBCError) |
318 | | }; |
319 | | |
320 | | #endif // OGR_ADBC_INCLUDED |