LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/hana - ogr_hana.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 35 37 94.6 %
Date: 2024-11-21 22:18:42 Functions: 15 16 93.8 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  SAP HANA Spatial Driver
       4             :  * Purpose:  SAP HANA Spatial OGR Driver Declarations.
       5             :  * Author:   Maxim Rylov
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2020, SAP SE
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #ifndef OGR_HANA_H_INCLUDED
      14             : #define OGR_HANA_H_INCLUDED
      15             : 
      16             : #include "hana/ogrhanautils.h"
      17             : #include "ogrsf_frmts.h"
      18             : #include "cpl_string.h"
      19             : 
      20             : #include <string>
      21             : #include <unordered_map>
      22             : #include <utility>
      23             : #include <vector>
      24             : 
      25             : #include "odbc/Forwards.h"
      26             : #include "odbc/Types.h"
      27             : 
      28             : class OGRHanaDataSource;
      29             : 
      30             : namespace OGRHANA
      31             : {
      32             : 
      33             : constexpr static int DEFAULT_BATCH_SIZE = 4 * 1024 * 1024;
      34             : constexpr static int DEFAULT_STRING_SIZE = 256;
      35             : 
      36             : constexpr static int UNDETERMINED_SRID = -1;
      37             : 
      38             : /************************************************************************/
      39             : /*                 Internal enum and struct definitions                 */
      40             : /************************************************************************/
      41             : 
      42             : class QGRHanaDataTypes
      43             : {
      44             :     QGRHanaDataTypes() = delete;
      45             : 
      46             :   public:
      47             :     /// Unknown data type.
      48             :     static constexpr int Unknown = odbc::SQLDataTypes::Unknown;
      49             :     /// 64-bit integer value.
      50             :     static constexpr int BigInt = odbc::SQLDataTypes::BigInt;
      51             :     /// Binary data of fixed length.
      52             :     static constexpr int Binary = odbc::SQLDataTypes::Binary;
      53             :     /// Single bit binary data.
      54             :     static constexpr int Bit = odbc::SQLDataTypes::Bit;
      55             :     /// Boolean value.
      56             :     static constexpr int Boolean = odbc::SQLDataTypes::Boolean;
      57             :     /// Character string of fixed string length.
      58             :     static constexpr int Char = odbc::SQLDataTypes::Char;
      59             :     /// Year, month, and day fields.
      60             :     static constexpr int Date = odbc::SQLDataTypes::Date;
      61             :     /// Year, month, and day fields.
      62             :     static constexpr int DateTime = odbc::SQLDataTypes::DateTime;
      63             :     /// Signed, exact, numeric value.
      64             :     static constexpr int Decimal = odbc::SQLDataTypes::Decimal;
      65             :     /// Double-precision floating point number.
      66             :     static constexpr int Double = odbc::SQLDataTypes::Double;
      67             :     /// Floating point number with driver-specific precision.
      68             :     static constexpr int Float = odbc::SQLDataTypes::Float;
      69             :     /// 32-bit integer value.
      70             :     static constexpr int Integer = odbc::SQLDataTypes::Integer;
      71             :     /// Variable length binary data.
      72             :     static constexpr int LongVarBinary = odbc::SQLDataTypes::LongVarBinary;
      73             :     /// Variable length character data.
      74             :     static constexpr int LongVarChar = odbc::SQLDataTypes::LongVarChar;
      75             :     /// Signed, exact, numeric value.
      76             :     static constexpr int Numeric = odbc::SQLDataTypes::Numeric;
      77             :     /// Single-precision floating point number.
      78             :     static constexpr int Real = odbc::SQLDataTypes::Real;
      79             :     /// 16-bit integer value.
      80             :     static constexpr int SmallInt = odbc::SQLDataTypes::SmallInt;
      81             :     /// Hour, minute, and second fields.
      82             :     static constexpr int Time = odbc::SQLDataTypes::Time;
      83             :     /// Year, month, day, hour, minute, and second fields.
      84             :     static constexpr int Timestamp = odbc::SQLDataTypes::Timestamp;
      85             :     /// 8-bit integer value.
      86             :     static constexpr int TinyInt = odbc::SQLDataTypes::TinyInt;
      87             :     /// Year, month, and day fields.
      88             :     static constexpr int TypeDate = odbc::SQLDataTypes::TypeDate;
      89             :     /// Hour, minute, and second fields.
      90             :     static constexpr int TypeTime = odbc::SQLDataTypes::TypeTime;
      91             :     /// Year, month, day, hour, minute, and second fields.
      92             :     static constexpr int TypeTimestamp = odbc::SQLDataTypes::TypeTimestamp;
      93             :     /// Variable length binary data.
      94             :     static constexpr int VarBinary = odbc::SQLDataTypes::VarBinary;
      95             :     /// Variable-length character string.
      96             :     static constexpr int VarChar = odbc::SQLDataTypes::VarChar;
      97             :     /// Unicode character string of fixed string length.
      98             :     static constexpr int WChar = odbc::SQLDataTypes::WChar;
      99             :     /// Unicode variable-length character data.
     100             :     static constexpr int WLongVarChar = odbc::SQLDataTypes::WLongVarChar;
     101             :     /// Unicode variable-length character string.
     102             :     static constexpr int WVarChar = odbc::SQLDataTypes::WVarChar;
     103             :     /// ST_GEOMETRY/ST_POINT value.
     104             :     static constexpr int Geometry = 29812;
     105             :     /// REAL_VECTOR value.
     106             :     static constexpr int RealVector = 29814;
     107             : };
     108             : 
     109             : struct ColumnDefinition
     110             : {
     111             :     CPLString name;
     112             :     CPLString typeDef;
     113             : };
     114             : 
     115             : struct AttributeColumnDescription
     116             : {
     117             :     CPLString name;
     118             :     short type = -1;
     119             :     CPLString typeName;
     120             :     int length = 0;  // the same type as in OGRFieldDefn.GetWidth
     121             :     unsigned short precision = 0;
     122             :     unsigned short scale = 0;
     123             :     bool isFeatureID = false;
     124             :     bool isArray = false;
     125             :     bool isAutoIncrement = false;
     126             :     bool isNullable = false;
     127             :     CPLString defaultValue;
     128             : };
     129             : 
     130             : struct GeometryColumnDescription
     131             : {
     132             :     CPLString name;
     133             :     OGRwkbGeometryType type;
     134             :     int srid;
     135             :     bool isNullable;
     136             : };
     137             : 
     138             : struct ColumnDescription
     139             : {
     140             :     bool isGeometry;
     141             :     AttributeColumnDescription attributeDescription;
     142             :     GeometryColumnDescription geometryDescription;
     143             : };
     144             : 
     145             : struct ColumnTypeInfo
     146             : {
     147             :     CPLString name;
     148             :     short type;
     149             :     int width;
     150             :     int precision;
     151             : };
     152             : 
     153             : struct Binary
     154             : {
     155             :     GByte *data;
     156             :     std::size_t size;
     157             : };
     158             : 
     159             : enum class BatchOperation
     160             : {
     161             :     NONE = 0,
     162             :     DELETE = 1,
     163             :     INSERT = 2,
     164             :     UPDATE = 4,
     165             :     ALL = 7
     166             : };
     167             : 
     168           8 : inline BatchOperation operator&(BatchOperation a, BatchOperation b)
     169             : {
     170             :     return static_cast<BatchOperation>(
     171             :         static_cast<std::underlying_type<BatchOperation>::type>(a) &
     172           8 :         static_cast<std::underlying_type<BatchOperation>::type>(b));
     173             : }
     174             : 
     175         144 : inline BatchOperation operator|(BatchOperation a, BatchOperation b)
     176             : {
     177             :     return static_cast<BatchOperation>(
     178             :         static_cast<std::underlying_type<BatchOperation>::type>(a) |
     179         144 :         static_cast<std::underlying_type<BatchOperation>::type>(b));
     180             : }
     181             : 
     182             : /************************************************************************/
     183             : /*                             OGRHanaLayer                             */
     184             : /************************************************************************/
     185             : 
     186             : class OGRHanaLayer : public OGRLayer
     187             : {
     188             :   protected:
     189             :     OGRHanaDataSource *dataSource_ = nullptr;
     190             :     OGRFeatureDefn *featureDefn_ = nullptr;
     191             :     GIntBig nextFeatureId_ = 0;
     192             :     std::vector<AttributeColumnDescription> attrColumns_;
     193             :     std::vector<GeometryColumnDescription> geomColumns_;
     194             :     int fidFieldIndex_ = OGRNullFID;
     195             :     CPLString fidFieldName_;
     196             :     CPLString rawQuery_;
     197             :     CPLString queryStatement_;
     198             :     CPLString whereClause_;
     199             :     CPLString attrFilter_;
     200             :     odbc::ResultSetRef resultSet_;
     201             :     std::vector<char> dataBuffer_;
     202             :     bool initialized_ = false;
     203             : 
     204             :     void EnsureInitialized();
     205             :     virtual OGRErr Initialize() = 0;
     206             : 
     207             :     void ClearQueryStatement();
     208             :     const CPLString &GetQueryStatement();
     209             :     void BuildWhereClause();
     210             :     void EnsureBufferCapacity(std::size_t size);
     211             :     virtual OGRFeature *GetNextFeatureInternal();
     212             :     int GetGeometryColumnSrid(int columnIndex) const;
     213             :     virtual OGRFeature *ReadFeature();
     214             :     OGRErr InitFeatureDefinition(const CPLString &schemaName,
     215             :                                  const CPLString &tableName,
     216             :                                  const CPLString &query,
     217             :                                  const CPLString &featureDefName);
     218             :     void ReadGeometryExtent(int geomField, OGREnvelope *extent, int force);
     219             :     bool IsFastExtentAvailable();
     220             : 
     221             :   public:
     222             :     explicit OGRHanaLayer(OGRHanaDataSource *datasource);
     223             :     ~OGRHanaLayer() override;
     224             : 
     225           0 :     virtual bool IsTableLayer() const
     226             :     {
     227           0 :         return false;
     228             :     }
     229             : 
     230             :     void ResetReading() override;
     231             : 
     232           2 :     OGRErr GetExtent(OGREnvelope *extent, int force = TRUE) override
     233             :     {
     234           2 :         return GetExtent(0, extent, force);
     235             :     }
     236             : 
     237             :     OGRErr GetExtent(int geomField, OGREnvelope *extent, int force) override;
     238             :     GIntBig GetFeatureCount(int force) override;
     239             :     OGRFeature *GetNextFeature() override;
     240             :     const char *GetFIDColumn() override;
     241             :     OGRFeatureDefn *GetLayerDefn() override;
     242             :     const char *GetName() override;
     243             : 
     244             :     OGRErr SetAttributeFilter(const char *pszQuery) override;
     245             : 
     246          20 :     void SetSpatialFilter(OGRGeometry *poGeom) override
     247             :     {
     248          20 :         SetSpatialFilter(0, poGeom);
     249          20 :     }
     250             : 
     251             :     void SetSpatialFilter(int iGeomField, OGRGeometry *poGeom) override;
     252             : };
     253             : 
     254             : /************************************************************************/
     255             : /*                             OGRHanaTableLayer                        */
     256             : /************************************************************************/
     257             : 
     258             : class OGRHanaTableLayer final : public OGRHanaLayer
     259             : {
     260             :   private:
     261             :     CPLString schemaName_;
     262             :     CPLString tableName_;
     263             :     bool updateMode_ = false;
     264             : 
     265             :     odbc::PreparedStatementRef currentIdentityValueStmt_;
     266             :     odbc::PreparedStatementRef insertFeatureStmtWithFID_;
     267             :     odbc::PreparedStatementRef insertFeatureStmtWithoutFID_;
     268             :     odbc::PreparedStatementRef deleteFeatureStmt_;
     269             :     odbc::PreparedStatementRef updateFeatureStmt_;
     270             : 
     271             :     bool allowAutoFIDOnCreateFeature_ = false;
     272             :     std::size_t batchSize_ = DEFAULT_BATCH_SIZE;
     273             :     std::size_t defaultStringSize_ = DEFAULT_STRING_SIZE;
     274             :     bool launderColumnNames_ = true;
     275             :     bool preservePrecision_ = true;
     276             :     std::vector<ColumnDefinition> customColumnDefs_;
     277             :     bool parseFunctionsChecked_ = false;
     278             : 
     279             :     OGRErr Initialize() override;
     280             :     std::pair<OGRErr, std::size_t>
     281             :     ExecuteUpdate(odbc::PreparedStatement &statement, bool withBatch,
     282             :                   const char *functionName);
     283             :     odbc::PreparedStatementRef CreateDeleteFeatureStatement();
     284             :     odbc::PreparedStatementRef CreateInsertFeatureStatement(bool withFID);
     285             :     odbc::PreparedStatementRef CreateUpdateFeatureStatement();
     286             :     void ResetPreparedStatements();
     287             :     OGRErr SetStatementParameters(odbc::PreparedStatement &statement,
     288             :                                   OGRFeature *feature, bool newFeature,
     289             :                                   bool withFID, const char *functionName);
     290             : 
     291             :     OGRErr ExecutePendingBatches(BatchOperation op);
     292             :     bool HasPendingBatches() const;
     293             :     ColumnTypeInfo GetColumnTypeInfo(const OGRFieldDefn &field) const;
     294             :     OGRErr GetGeometryWkb(OGRFeature *feature, int fieldIndex, Binary &binary);
     295             :     void ClearBatches();
     296             :     void ColumnsChanged();
     297             : 
     298             :   public:
     299             :     OGRHanaTableLayer(OGRHanaDataSource *datasource, const char *schemaName,
     300             :                       const char *tableName, int update);
     301             :     ~OGRHanaTableLayer() override;
     302             : 
     303         121 :     bool IsTableLayer() const override
     304             :     {
     305         121 :         return true;
     306             :     }
     307             : 
     308             :     OGRErr DropTable();
     309             : 
     310             :     void ResetReading() override;
     311             : 
     312           2 :     OGRErr GetExtent(OGREnvelope *extent, int force = TRUE) override
     313             :     {
     314           2 :         return GetExtent(0, extent, force);
     315             :     }
     316             : 
     317             :     OGRErr GetExtent(int geomField, OGREnvelope *extent, int force) override;
     318             :     GIntBig GetFeatureCount(int force) override;
     319             : 
     320         592 :     const char *GetName() override
     321             :     {
     322         592 :         return tableName_.c_str();
     323             :     }
     324             : 
     325             :     int TestCapability(const char *capabilities) override;
     326             : 
     327             :     OGRErr ICreateFeature(OGRFeature *feature) override;
     328             :     OGRErr DeleteFeature(GIntBig nFID) override;
     329             :     OGRErr ISetFeature(OGRFeature *feature) override;
     330             : 
     331             :     OGRErr CreateField(const OGRFieldDefn *field, int approxOK = TRUE) override;
     332             :     OGRErr CreateGeomField(const OGRGeomFieldDefn *geomField,
     333             :                            int approxOK = TRUE) override;
     334             :     OGRErr DeleteField(int field) override;
     335             :     OGRErr AlterFieldDefn(int field, OGRFieldDefn *newFieldDefn,
     336             :                           int flagsIn) override;
     337             : 
     338          18 :     void SetBatchSize(std::size_t size)
     339             :     {
     340          18 :         batchSize_ = size;
     341          18 :     }
     342             : 
     343          18 :     void SetDefaultStringSize(std::size_t size)
     344             :     {
     345          18 :         defaultStringSize_ = size;
     346          18 :     }
     347             : 
     348          18 :     void SetLaunderFlag(bool flag)
     349             :     {
     350          18 :         launderColumnNames_ = flag;
     351          18 :     }
     352             : 
     353             :     void SetCustomColumnTypes(const char *columnTypes);
     354             : 
     355          18 :     void SetPrecisionFlag(bool flag)
     356             :     {
     357          18 :         preservePrecision_ = flag;
     358          18 :     }
     359             : 
     360             :     OGRErr StartTransaction() override;
     361             :     OGRErr CommitTransaction() override;
     362             :     OGRErr RollbackTransaction() override;
     363             : 
     364             :     void FlushPendingBatches(bool commit);
     365             : };
     366             : 
     367             : /************************************************************************/
     368             : /*                              OGRHanaResultLayer                      */
     369             : /************************************************************************/
     370             : 
     371             : class OGRHanaResultLayer final : public OGRHanaLayer
     372             : {
     373             :     OGRErr Initialize() override;
     374             : 
     375             :   public:
     376             :     explicit OGRHanaResultLayer(OGRHanaDataSource *datasource,
     377             :                                 const char *query);
     378             : 
     379             :     int TestCapability(const char *capabilities) override;
     380             : };
     381             : 
     382             : }  // namespace OGRHANA
     383             : 
     384             : /************************************************************************/
     385             : /*                          OGRHanaDataSource                          */
     386             : /************************************************************************/
     387             : 
     388             : class OGRHanaDataSource final : public GDALDataset
     389             : {
     390             :   private:
     391             :     friend class OGRHANA::OGRHanaLayer;
     392             :     friend class OGRHANA::OGRHanaTableLayer;
     393             :     friend class OGRHANA::OGRHanaResultLayer;
     394             : 
     395             :     using SrsCache = std::unordered_map<int, OGRSpatialReference *>;
     396             : 
     397             :     CPLString schemaName_;
     398             :     bool updateMode_ = false;
     399             :     bool detectGeometryType_ = true;
     400             :     bool isTransactionStarted_ = false;
     401             :     std::vector<std::unique_ptr<OGRLayer>> layers_;
     402             :     SrsCache srsCache_;
     403             :     odbc::EnvironmentRef connEnv_;
     404             :     odbc::ConnectionRef conn_;
     405             :     OGRHANA::HanaVersion hanaVersion_;
     406             :     OGRHANA::HanaVersion cloudVersion_;
     407             : 
     408             :   private:
     409             :     void CreateTable(const CPLString &tableName, const CPLString &fidName,
     410             :                      const CPLString &fidType, const CPLString &geomColumnName,
     411             :                      OGRwkbGeometryType geomType, bool geomColumnNullable,
     412             :                      const CPLString &geomColumnIndexType, int geomSrid);
     413             :     void DetermineVersions();
     414             : 
     415             :   protected:
     416             :     std::pair<CPLString, CPLString> FindSchemaAndTableNames(const char *query);
     417             :     int FindLayerByName(const char *name);
     418             :     CPLString FindSchemaName(const char *objectName);
     419             : 
     420             :     odbc::StatementRef CreateStatement();
     421             :     odbc::PreparedStatementRef PrepareStatement(const char *sql);
     422             :     void Commit();
     423             :     void ExecuteSQL(const CPLString &sql);
     424             : 
     425             :     OGRSpatialReference *GetSrsById(int srid);
     426             :     int GetSrsId(const OGRSpatialReference *srs);
     427             :     bool IsSrsRoundEarth(int srid);
     428             :     bool HasSrsPlanarEquivalent(int srid);
     429             :     OGRErr GetQueryColumns(
     430             :         const CPLString &schemaName, const CPLString &query,
     431             :         std::vector<OGRHANA::ColumnDescription> &columnDescriptions);
     432             :     std::vector<CPLString> GetTablePrimaryKeys(const char *schemaName,
     433             :                                                const char *tableName);
     434             : 
     435             :     void InitializeLayers(const char *schemaName, const char *tableNames);
     436             :     void CreateSpatialReferenceSystem(const OGRSpatialReference &srs, int srid,
     437             :                                       const char *authorityName,
     438             :                                       int authorityCode, const CPLString &wkt,
     439             :                                       const CPLString &proj4);
     440             : 
     441             :     std::pair<OGRErr, CPLString> LaunderName(const char *name);
     442             : 
     443         372 :     bool IsTransactionStarted() const
     444             :     {
     445         372 :         return isTransactionStarted_;
     446             :     }
     447             : 
     448             :     void CreateParseArrayFunctions(const char *schemaName);
     449             :     bool ParseArrayFunctionsExist(const char *schemaName);
     450             : 
     451             :   public:
     452             :     static const char *GetPrefix();
     453             : 
     454             :   public:
     455             :     OGRHanaDataSource();
     456             :     ~OGRHanaDataSource() override;
     457             : 
     458             :     int Open(const char *newName, char **options, int update);
     459             : 
     460          40 :     OGRHANA::HanaVersion GetHanaVersion() const
     461             :     {
     462          40 :         return hanaVersion_;
     463             :     }
     464             : 
     465          16 :     OGRHANA::HanaVersion GetHanaCloudVersion() const
     466             :     {
     467          16 :         return cloudVersion_;
     468             :     }
     469             : 
     470             :     OGRErr DeleteLayer(int index) override;
     471             : 
     472           2 :     int GetLayerCount() override
     473             :     {
     474           2 :         return static_cast<int>(layers_.size());
     475             :     }
     476             : 
     477             :     OGRLayer *GetLayer(int index) override;
     478             :     OGRLayer *GetLayerByName(const char *) override;
     479             :     OGRLayer *ICreateLayer(const char *pszName,
     480             :                            const OGRGeomFieldDefn *poGeomFieldDefn,
     481             :                            CSLConstList papszOptions) override;
     482             :     int TestCapability(const char *capabilities) override;
     483             : 
     484             :     OGRLayer *ExecuteSQL(const char *sqlCommand, OGRGeometry *spatialFilter,
     485             :                          const char *dialect) override;
     486             : 
     487             :     OGRErr StartTransaction(int bForce = FALSE) override;
     488             :     OGRErr CommitTransaction() override;
     489             :     OGRErr RollbackTransaction() override;
     490             : };
     491             : 
     492             : #endif /* ndef OGR_HANA_H_INCLUDED */

Generated by: LCOV version 1.14