LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/mssqlspatial - ogrmssqlspatiallayer.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 0 322 0.0 %
Date: 2024-05-04 12:52:34 Functions: 0 18 0.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  MSSQL Spatial driver
       4             :  * Purpose:  Definition of classes for OGR MSSQL Spatial driver.
       5             :  * Author:   Tamas Szekeres, szekerest at gmail.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2010, Tamas Szekeres
       9             :  *
      10             :  * Permission is hereby granted, free of charge, to any person obtaining a
      11             :  * copy of this software and associated documentation files (the "Software"),
      12             :  * to deal in the Software without restriction, including without limitation
      13             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      14             :  * and/or sell copies of the Software, and to permit persons to whom the
      15             :  * Software is furnished to do so, subject to the following conditions:
      16             :  *
      17             :  * The above copyright notice and this permission notice shall be included
      18             :  * in all copies or substantial portions of the Software.
      19             :  *
      20             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      21             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      22             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      23             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      24             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      25             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      26             :  * DEALINGS IN THE SOFTWARE.
      27             :  ****************************************************************************/
      28             : 
      29             : #include "ogr_mssqlspatial.h"
      30             : 
      31             : /************************************************************************/
      32             : /*                        OGRMSSQLSpatialLayer()                        */
      33             : /************************************************************************/
      34             : 
      35           0 : OGRMSSQLSpatialLayer::OGRMSSQLSpatialLayer(OGRMSSQLSpatialDataSource *poDSIn)
      36           0 :     : poDS(poDSIn)
      37             : 
      38             : {
      39           0 : }
      40             : 
      41             : /************************************************************************/
      42             : /*                      ~OGRMSSQLSpatialLayer()                         */
      43             : /************************************************************************/
      44             : 
      45           0 : OGRMSSQLSpatialLayer::~OGRMSSQLSpatialLayer()
      46             : 
      47             : {
      48           0 :     if (m_nFeaturesRead > 0 && poFeatureDefn != nullptr)
      49             :     {
      50           0 :         CPLDebug("OGR_MSSQLSpatial", "%d features read on layer '%s'.",
      51           0 :                  (int)m_nFeaturesRead, poFeatureDefn->GetName());
      52             :     }
      53             : 
      54           0 :     ClearStatement();
      55             : 
      56           0 :     CPLFree(pszGeomColumn);
      57           0 :     CPLFree(pszFIDColumn);
      58           0 :     CPLFree(panFieldOrdinals);
      59             : 
      60           0 :     if (poFeatureDefn)
      61             :     {
      62           0 :         poFeatureDefn->Release();
      63           0 :         poFeatureDefn = nullptr;
      64             :     }
      65             : 
      66           0 :     if (poSRS)
      67           0 :         poSRS->Release();
      68           0 : }
      69             : 
      70             : /************************************************************************/
      71             : /*                          BuildFeatureDefn()                          */
      72             : /*                                                                      */
      73             : /*      Build feature definition from a set of column definitions       */
      74             : /*      set on a statement.  Sift out geometry and FID fields.          */
      75             : /************************************************************************/
      76             : 
      77           0 : void OGRMSSQLSpatialLayer::BuildFeatureDefn(const char *pszLayerName,
      78             :                                             CPLODBCStatement *poStmtIn)
      79             : 
      80             : {
      81             :     bool bShowFidColumn =
      82           0 :         CPLTestBool(CPLGetConfigOption("MSSQLSPATIAL_SHOW_FID_COLUMN", "NO"));
      83             : 
      84           0 :     if (!poFeatureDefn)
      85             :     {
      86           0 :         poFeatureDefn = new OGRFeatureDefn(pszLayerName);
      87           0 :         poFeatureDefn->Reference();
      88             :     }
      89             :     else
      90             :     {
      91           0 :         for (int iFieldIdx = poFeatureDefn->GetFieldCount() - 1; iFieldIdx >= 0;
      92             :              --iFieldIdx)
      93             :         {
      94           0 :             poFeatureDefn->DeleteFieldDefn(iFieldIdx);
      95             :         }
      96           0 :         for (int iFieldIdx = poFeatureDefn->GetGeomFieldCount() - 1;
      97           0 :              iFieldIdx >= 0; --iFieldIdx)
      98             :         {
      99           0 :             poFeatureDefn->DeleteGeomFieldDefn(iFieldIdx);
     100             :         }
     101           0 :         poFeatureDefn->SetName(pszLayerName);
     102             :     }
     103             : 
     104           0 :     nRawColumns = poStmtIn->GetColCount();
     105             : 
     106           0 :     CPLFree(panFieldOrdinals);
     107           0 :     panFieldOrdinals = (int *)CPLMalloc(sizeof(int) * nRawColumns);
     108             : 
     109           0 :     for (int iCol = 0; iCol < nRawColumns; iCol++)
     110             :     {
     111           0 :         if (pszGeomColumn == nullptr)
     112             :         {
     113             :             /* need to identify the geometry column */
     114           0 :             if (EQUAL(poStmtIn->GetColTypeName(iCol), "geometry"))
     115             :             {
     116           0 :                 nGeomColumnType = MSSQLCOLTYPE_GEOMETRY;
     117           0 :                 pszGeomColumn = CPLStrdup(poStmtIn->GetColName(iCol));
     118           0 :                 if (poFeatureDefn->GetGeomFieldCount() == 1)
     119             :                 {
     120           0 :                     poFeatureDefn->GetGeomFieldDefn(0)->SetNullable(
     121           0 :                         poStmtIn->GetColNullable(iCol));
     122           0 :                     poFeatureDefn->GetGeomFieldDefn(0)->SetName(pszGeomColumn);
     123             :                 }
     124           0 :                 nGeomColumnIndex = iCol;
     125           0 :                 continue;
     126             :             }
     127           0 :             else if (EQUAL(poStmtIn->GetColTypeName(iCol), "geography"))
     128             :             {
     129           0 :                 nGeomColumnType = MSSQLCOLTYPE_GEOGRAPHY;
     130           0 :                 pszGeomColumn = CPLStrdup(poStmtIn->GetColName(iCol));
     131           0 :                 if (poFeatureDefn->GetGeomFieldCount() == 1)
     132             :                 {
     133           0 :                     poFeatureDefn->GetGeomFieldDefn(0)->SetNullable(
     134           0 :                         poStmtIn->GetColNullable(iCol));
     135           0 :                     poFeatureDefn->GetGeomFieldDefn(0)->SetName(pszGeomColumn);
     136             :                 }
     137           0 :                 nGeomColumnIndex = iCol;
     138           0 :                 continue;
     139             :             }
     140             :         }
     141             :         else
     142             :         {
     143           0 :             if (EQUAL(poStmtIn->GetColName(iCol), pszGeomColumn))
     144             :             {
     145           0 :                 if (poFeatureDefn->GetGeomFieldCount() == 1)
     146             :                 {
     147           0 :                     poFeatureDefn->GetGeomFieldDefn(0)->SetNullable(
     148           0 :                         poStmtIn->GetColNullable(iCol));
     149           0 :                     poFeatureDefn->GetGeomFieldDefn(0)->SetName(pszGeomColumn);
     150             :                 }
     151           0 :                 nGeomColumnIndex = iCol;
     152           0 :                 continue;
     153             :             }
     154             :         }
     155             : 
     156           0 :         if (pszFIDColumn != nullptr)
     157             :         {
     158           0 :             if (EQUAL(poStmtIn->GetColName(iCol), pszFIDColumn))
     159             :             {
     160           0 :                 bool bIntegerFID = false;
     161           0 :                 switch (CPLODBCStatement::GetTypeMapping(
     162           0 :                     poStmtIn->GetColType(iCol)))
     163             :                 {
     164           0 :                     case SQL_C_SSHORT:
     165             :                     case SQL_C_USHORT:
     166             :                     case SQL_C_SLONG:
     167             :                     case SQL_C_ULONG:
     168             :                     case SQL_C_SBIGINT:
     169             :                     case SQL_C_UBIGINT:
     170           0 :                         bIntegerFID = true;
     171           0 :                         break;
     172           0 :                     default:
     173           0 :                         break;
     174             :                 }
     175           0 :                 if (!bIntegerFID)
     176             :                 {
     177           0 :                     CPLDebug(
     178             :                         "MSSQL",
     179             :                         "Ignoring FID column %s as it is of non integer type",
     180             :                         pszFIDColumn);
     181           0 :                     CPLFree(pszFIDColumn);
     182           0 :                     pszFIDColumn = nullptr;
     183             :                 }
     184             :                 else
     185             :                 {
     186           0 :                     if (STARTS_WITH_CI(poStmtIn->GetColTypeName(iCol),
     187             :                                        "bigint"))
     188           0 :                         SetMetadataItem(OLMD_FID64, "YES");
     189             : 
     190           0 :                     if (EQUAL(poStmtIn->GetColTypeName(iCol), "int identity") ||
     191           0 :                         EQUAL(poStmtIn->GetColTypeName(iCol),
     192             :                               "bigint identity"))
     193           0 :                         bIsIdentityFid = TRUE;
     194             : 
     195           0 :                     nFIDColumnIndex = iCol;
     196             : 
     197           0 :                     if (!bShowFidColumn)
     198           0 :                         continue;
     199             :                 }
     200             :             }
     201             :         }
     202             :         else
     203             :         {
     204           0 :             if (EQUAL(poStmtIn->GetColTypeName(iCol), "int identity"))
     205             :             {
     206           0 :                 pszFIDColumn = CPLStrdup(poStmtIn->GetColName(iCol));
     207           0 :                 bIsIdentityFid = TRUE;
     208           0 :                 nFIDColumnIndex = iCol;
     209             : 
     210           0 :                 if (!bShowFidColumn)
     211           0 :                     continue;
     212             :             }
     213           0 :             else if (EQUAL(poStmtIn->GetColTypeName(iCol), "bigint identity"))
     214             :             {
     215           0 :                 pszFIDColumn = CPLStrdup(poStmtIn->GetColName(iCol));
     216           0 :                 bIsIdentityFid = TRUE;
     217           0 :                 SetMetadataItem(OLMD_FID64, "YES");
     218           0 :                 nFIDColumnIndex = iCol;
     219             : 
     220           0 :                 if (!bShowFidColumn)
     221           0 :                     continue;
     222             :             }
     223             :         }
     224             : 
     225           0 :         OGRFieldDefn oField(poStmtIn->GetColName(iCol), OFTString);
     226             : 
     227           0 :         switch (CPLODBCStatement::GetTypeMapping(poStmtIn->GetColType(iCol)))
     228             :         {
     229           0 :             case SQL_C_SSHORT:
     230           0 :                 oField.SetType(OFTInteger);
     231           0 :                 oField.SetSubType(OFSTInt16);
     232           0 :                 break;
     233             : 
     234           0 :             case SQL_C_USHORT:
     235             :             case SQL_C_SLONG:
     236             :             case SQL_C_ULONG:
     237           0 :                 oField.SetType(OFTInteger);
     238           0 :                 break;
     239             : 
     240           0 :             case SQL_C_SBIGINT:
     241             :             case SQL_C_UBIGINT:
     242           0 :                 oField.SetType(OFTInteger64);
     243           0 :                 break;
     244             : 
     245           0 :             case SQL_C_BINARY:
     246           0 :                 oField.SetType(OFTBinary);
     247           0 :                 oField.SetWidth(MAX(0, poStmtIn->GetColSize(iCol)));
     248           0 :                 break;
     249             : 
     250           0 :             case SQL_C_NUMERIC:
     251           0 :                 oField.SetType(OFTReal);
     252           0 :                 oField.SetPrecision(poStmtIn->GetColPrecision(iCol));
     253           0 :                 oField.SetWidth(MAX(0, poStmtIn->GetColSize(iCol)));
     254           0 :                 if (oField.GetPrecision() == 0 && oField.GetWidth() <= 9)
     255           0 :                     oField.SetType(OFTInteger);
     256           0 :                 else if (oField.GetPrecision() == 0 && oField.GetWidth() <= 18)
     257           0 :                     oField.SetType(OFTInteger64);
     258           0 :                 break;
     259             : 
     260           0 :             case SQL_C_FLOAT:
     261           0 :                 oField.SetType(OFTReal);
     262           0 :                 oField.SetSubType(OFSTFloat32);
     263           0 :                 break;
     264             : 
     265           0 :             case SQL_C_DOUBLE:
     266           0 :                 oField.SetType(OFTReal);
     267           0 :                 break;
     268             : 
     269           0 :             case SQL_C_DATE:
     270           0 :                 oField.SetType(OFTDate);
     271           0 :                 break;
     272             : 
     273           0 :             case SQL_C_TIME:
     274           0 :                 oField.SetType(OFTTime);
     275           0 :                 break;
     276             : 
     277           0 :             case SQL_C_TIMESTAMP:
     278           0 :                 oField.SetType(OFTDateTime);
     279           0 :                 break;
     280             : 
     281           0 :             case SQL_C_GUID:
     282           0 :                 m_bHasUUIDColumn = true;
     283           0 :                 oField.SetType(OFTString);
     284           0 :                 oField.SetSubType(OFSTUUID);
     285           0 :                 break;
     286             : 
     287           0 :             default:
     288           0 :                 oField.SetWidth(MAX(0, poStmtIn->GetColSize(iCol)));
     289             :                 /* leave it as OFTString */;
     290             :         }
     291             : 
     292           0 :         oField.SetNullable(poStmtIn->GetColNullable(iCol));
     293             : 
     294           0 :         if (poStmtIn->GetColColumnDef(iCol))
     295             :         {
     296             :             /* process default value specification */
     297           0 :             if (EQUAL(poStmtIn->GetColColumnDef(iCol), "(getdate())"))
     298           0 :                 oField.SetDefault("CURRENT_TIMESTAMP");
     299           0 :             else if (STARTS_WITH_CI(poStmtIn->GetColColumnDef(iCol),
     300             :                                     "(CONVERT([time],getdate()"))
     301           0 :                 oField.SetDefault("CURRENT_TIME");
     302           0 :             else if (STARTS_WITH_CI(poStmtIn->GetColColumnDef(iCol),
     303             :                                     "(CONVERT([date],getdate()"))
     304           0 :                 oField.SetDefault("CURRENT_DATE");
     305             :             else
     306             :             {
     307           0 :                 char *pszDefault = CPLStrdup(poStmtIn->GetColColumnDef(iCol));
     308           0 :                 int nLen = static_cast<int>(strlen(pszDefault));
     309           0 :                 if (nLen >= 1 && pszDefault[0] == '(' &&
     310           0 :                     pszDefault[nLen - 1] == ')')
     311             :                 {
     312             :                     // All default values are encapsulated in brackets
     313             :                     // by MSSQL server.
     314           0 :                     if (nLen >= 4 && pszDefault[1] == '(' &&
     315           0 :                         pszDefault[nLen - 2] == ')')
     316             :                     {
     317             :                         /* for numeric values double brackets are used */
     318           0 :                         pszDefault[nLen - 2] = '\0';
     319           0 :                         oField.SetDefault(pszDefault + 2);
     320             :                     }
     321             :                     else
     322             :                     {
     323           0 :                         pszDefault[nLen - 1] = '\0';
     324           0 :                         oField.SetDefault(pszDefault + 1);
     325             :                     }
     326             :                 }
     327             :                 else
     328           0 :                     oField.SetDefault(pszDefault);
     329             : 
     330           0 :                 CPLFree(pszDefault);
     331             :             }
     332             :         }
     333             : 
     334           0 :         poFeatureDefn->AddFieldDefn(&oField);
     335           0 :         panFieldOrdinals[poFeatureDefn->GetFieldCount() - 1] = iCol;
     336             :     }
     337             : 
     338             :     /* -------------------------------------------------------------------- */
     339             :     /*      If we don't already have an FID, check if there is a special    */
     340             :     /*      FID named column available.                                     */
     341             :     /* -------------------------------------------------------------------- */
     342           0 :     if (pszFIDColumn == nullptr)
     343             :     {
     344             :         const char *pszOGR_FID =
     345           0 :             CPLGetConfigOption("MSSQLSPATIAL_OGR_FID", "OGR_FID");
     346           0 :         if (poFeatureDefn->GetFieldIndex(pszOGR_FID) != -1)
     347           0 :             pszFIDColumn = CPLStrdup(pszOGR_FID);
     348             :     }
     349             : 
     350           0 :     if (pszFIDColumn != nullptr)
     351           0 :         CPLDebug("OGR_MSSQLSpatial", "Using column %s as FID for table %s.",
     352           0 :                  pszFIDColumn, poFeatureDefn->GetName());
     353             :     else
     354           0 :         CPLDebug("OGR_MSSQLSpatial", "Table %s has no identified FID column.",
     355           0 :                  poFeatureDefn->GetName());
     356           0 : }
     357             : 
     358             : /************************************************************************/
     359             : /*                           ClearStatement()                           */
     360             : /************************************************************************/
     361             : 
     362           0 : void OGRMSSQLSpatialLayer::ClearStatement()
     363             : 
     364             : {
     365           0 :     if (poStmt != nullptr)
     366             :     {
     367           0 :         delete poStmt;
     368           0 :         poStmt = nullptr;
     369             :     }
     370           0 : }
     371             : 
     372             : /************************************************************************/
     373             : /*                            ResetReading()                            */
     374             : /************************************************************************/
     375             : 
     376           0 : void OGRMSSQLSpatialLayer::ResetReading()
     377             : 
     378             : {
     379           0 :     if (m_bResetNeeded)
     380             :     {
     381           0 :         iNextShapeId = 0;
     382           0 :         ClearStatement();
     383           0 :         m_bEOF = false;
     384           0 :         m_bResetNeeded = false;
     385             :     }
     386           0 : }
     387             : 
     388             : /************************************************************************/
     389             : /*                           GetNextFeature()                           */
     390             : /************************************************************************/
     391             : 
     392           0 : OGRFeature *OGRMSSQLSpatialLayer::GetNextFeature()
     393             : 
     394             : {
     395           0 :     if (m_bEOF)
     396           0 :         return nullptr;
     397             : 
     398             :     while (true)
     399             :     {
     400             :         OGRFeature *poFeature;
     401             : 
     402           0 :         poFeature = GetNextRawFeature();
     403           0 :         if (poFeature == nullptr)
     404             :         {
     405           0 :             m_bEOF = true;
     406           0 :             return nullptr;
     407             :         }
     408             : 
     409           0 :         if ((m_poFilterGeom == nullptr ||
     410           0 :              FilterGeometry(poFeature->GetGeometryRef())) &&
     411           0 :             (m_poAttrQuery == nullptr || m_poAttrQuery->Evaluate(poFeature)))
     412           0 :             return poFeature;
     413             : 
     414           0 :         delete poFeature;
     415           0 :     }
     416             : }
     417             : 
     418             : /************************************************************************/
     419             : /*                         GetNextRawFeature()                          */
     420             : /************************************************************************/
     421             : 
     422           0 : OGRFeature *OGRMSSQLSpatialLayer::GetNextRawFeature()
     423             : 
     424             : {
     425           0 :     m_bResetNeeded = true;
     426           0 :     if (GetStatement() == nullptr)
     427           0 :         return nullptr;
     428             : 
     429             :     /* -------------------------------------------------------------------- */
     430             :     /*      If we are marked to restart then do so, and fetch a record.     */
     431             :     /* -------------------------------------------------------------------- */
     432           0 :     if (!poStmt->Fetch())
     433             :     {
     434           0 :         delete poStmt;
     435           0 :         poStmt = nullptr;
     436           0 :         return nullptr;
     437             :     }
     438             : 
     439             :     /* -------------------------------------------------------------------- */
     440             :     /*      Create a feature from the current result.                       */
     441             :     /* -------------------------------------------------------------------- */
     442           0 :     OGRFeature *poFeature = new OGRFeature(poFeatureDefn);
     443             : 
     444             :     const char *pszFID;
     445           0 :     if (pszFIDColumn != nullptr && poStmt->GetColId(pszFIDColumn) > -1 &&
     446           0 :         (pszFID = poStmt->GetColData(poStmt->GetColId(pszFIDColumn))) !=
     447             :             nullptr)
     448           0 :         poFeature->SetFID(CPLAtoGIntBig(pszFID));
     449             :     else
     450           0 :         poFeature->SetFID(iNextShapeId);
     451             : 
     452           0 :     iNextShapeId++;
     453           0 :     m_nFeaturesRead++;
     454             : 
     455             :     /* -------------------------------------------------------------------- */
     456             :     /*      Set the fields.                                                 */
     457             :     /* -------------------------------------------------------------------- */
     458           0 :     for (int iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++)
     459             :     {
     460           0 :         if (poFeatureDefn->GetFieldDefn(iField)->IsIgnored())
     461           0 :             continue;
     462             : 
     463           0 :         int iSrcField = panFieldOrdinals[iField];
     464           0 :         const char *pszValue = poStmt->GetColData(iSrcField);
     465             : 
     466           0 :         if (pszValue == nullptr)
     467           0 :             poFeature->SetFieldNull(iField);
     468           0 :         else if (poFeature->GetFieldDefnRef(iField)->GetType() == OFTBinary)
     469           0 :             poFeature->SetField(iField, poStmt->GetColDataLength(iSrcField),
     470             :                                 (GByte *)pszValue);
     471             :         else
     472           0 :             poFeature->SetField(iField, pszValue);
     473             :     }
     474             : 
     475             :     /* -------------------------------------------------------------------- */
     476             :     /*      Try to extract a geometry.                                      */
     477             :     /* -------------------------------------------------------------------- */
     478           0 :     if (pszGeomColumn != nullptr && !poFeatureDefn->IsGeometryIgnored())
     479             :     {
     480           0 :         int iField = poStmt->GetColId(pszGeomColumn);
     481           0 :         const char *pszGeomText = poStmt->GetColData(iField);
     482           0 :         OGRGeometry *poGeom = nullptr;
     483           0 :         OGRErr eErr = OGRERR_NONE;
     484             : 
     485           0 :         if (pszGeomText != nullptr)
     486             :         {
     487           0 :             int nLength = poStmt->GetColDataLength(iField);
     488             : 
     489           0 :             if (nGeomColumnType == MSSQLCOLTYPE_GEOMETRY ||
     490           0 :                 nGeomColumnType == MSSQLCOLTYPE_GEOGRAPHY ||
     491           0 :                 nGeomColumnType == MSSQLCOLTYPE_BINARY)
     492             :             {
     493           0 :                 switch (poDS->GetGeometryFormat())
     494             :                 {
     495           0 :                     case MSSQLGEOMETRY_NATIVE:
     496             :                     {
     497           0 :                         OGRMSSQLGeometryParser oParser(nGeomColumnType);
     498           0 :                         eErr = oParser.ParseSqlGeometry(
     499             :                             (unsigned char *)pszGeomText, nLength, &poGeom);
     500           0 :                         nSRSId = oParser.GetSRSId();
     501             :                     }
     502           0 :                     break;
     503           0 :                     case MSSQLGEOMETRY_WKB:
     504             :                     case MSSQLGEOMETRY_WKBZM:
     505           0 :                         eErr = OGRGeometryFactory::createFromWkb(
     506             :                             pszGeomText, nullptr, &poGeom, nLength);
     507           0 :                         break;
     508           0 :                     case MSSQLGEOMETRY_WKT:
     509           0 :                         eErr = OGRGeometryFactory::createFromWkt(
     510             :                             pszGeomText, nullptr, &poGeom);
     511           0 :                         break;
     512           0 :                 }
     513             :             }
     514           0 :             else if (nGeomColumnType == MSSQLCOLTYPE_TEXT)
     515             :             {
     516           0 :                 eErr = OGRGeometryFactory::createFromWkt(pszGeomText, nullptr,
     517             :                                                          &poGeom);
     518             :             }
     519             :         }
     520             : 
     521           0 :         if (eErr != OGRERR_NONE)
     522             :         {
     523             :             const char *pszMessage;
     524             : 
     525           0 :             switch (eErr)
     526             :             {
     527           0 :                 case OGRERR_NOT_ENOUGH_DATA:
     528           0 :                     pszMessage = "Not enough data to deserialize";
     529           0 :                     break;
     530           0 :                 case OGRERR_UNSUPPORTED_GEOMETRY_TYPE:
     531           0 :                     pszMessage = "Unsupported geometry type";
     532           0 :                     break;
     533           0 :                 case OGRERR_CORRUPT_DATA:
     534           0 :                     pszMessage = "Corrupt data";
     535           0 :                     break;
     536           0 :                 default:
     537           0 :                     pszMessage = "Unrecognized error";
     538             :             }
     539           0 :             CPLError(CE_Failure, CPLE_AppDefined, "GetNextRawFeature(): %s",
     540             :                      pszMessage);
     541             :         }
     542             : 
     543           0 :         if (poGeom != nullptr)
     544             :         {
     545           0 :             if (GetSpatialRef())
     546           0 :                 poGeom->assignSpatialReference(poSRS);
     547             : 
     548           0 :             poFeature->SetGeometryDirectly(poGeom);
     549             :         }
     550             :     }
     551             : 
     552           0 :     return poFeature;
     553             : }
     554             : 
     555             : /************************************************************************/
     556             : /*                             GetFeature()                             */
     557             : /************************************************************************/
     558             : 
     559           0 : OGRFeature *OGRMSSQLSpatialLayer::GetFeature(GIntBig nFeatureId)
     560             : 
     561             : {
     562             :     /* This should be implemented directly! */
     563             : 
     564           0 :     return OGRLayer::GetFeature(nFeatureId);
     565             : }
     566             : 
     567             : /************************************************************************/
     568             : /*                           TestCapability()                           */
     569             : /************************************************************************/
     570             : 
     571           0 : int OGRMSSQLSpatialLayer::TestCapability(CPL_UNUSED const char *pszCap)
     572             : {
     573           0 :     return FALSE;
     574             : }
     575             : 
     576             : /************************************************************************/
     577             : /*                          StartTransaction()                          */
     578             : /************************************************************************/
     579             : 
     580           0 : OGRErr OGRMSSQLSpatialLayer::StartTransaction()
     581             : 
     582             : {
     583           0 :     if (!poDS->GetSession()->BeginTransaction())
     584             :     {
     585           0 :         CPLError(CE_Failure, CPLE_AppDefined, "Failed to start transaction: %s",
     586           0 :                  poDS->GetSession()->GetLastError());
     587           0 :         return OGRERR_FAILURE;
     588             :     }
     589           0 :     return OGRERR_NONE;
     590             : }
     591             : 
     592             : /************************************************************************/
     593             : /*                         CommitTransaction()                          */
     594             : /************************************************************************/
     595             : 
     596           0 : OGRErr OGRMSSQLSpatialLayer::CommitTransaction()
     597             : 
     598             : {
     599           0 :     if (!poDS->GetSession()->CommitTransaction())
     600             :     {
     601           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     602             :                  "Failed to commit transaction: %s",
     603           0 :                  poDS->GetSession()->GetLastError());
     604           0 :         return OGRERR_FAILURE;
     605             :     }
     606           0 :     return OGRERR_NONE;
     607             : }
     608             : 
     609             : /************************************************************************/
     610             : /*                        RollbackTransaction()                         */
     611             : /************************************************************************/
     612             : 
     613           0 : OGRErr OGRMSSQLSpatialLayer::RollbackTransaction()
     614             : 
     615             : {
     616           0 :     if (!poDS->GetSession()->RollbackTransaction())
     617             :     {
     618           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     619             :                  "Failed to roll back transaction: %s",
     620           0 :                  poDS->GetSession()->GetLastError());
     621           0 :         return OGRERR_FAILURE;
     622             :     }
     623           0 :     return OGRERR_NONE;
     624             : }
     625             : 
     626             : /************************************************************************/
     627             : /*                           GetSpatialRef()                            */
     628             : /************************************************************************/
     629             : 
     630           0 : OGRSpatialReference *OGRMSSQLSpatialLayer::GetSpatialRef()
     631             : 
     632             : {
     633           0 :     if (poSRS == nullptr && nSRSId > 0)
     634             :     {
     635           0 :         poSRS = poDS->FetchSRS(nSRSId);
     636           0 :         if (poSRS != nullptr)
     637           0 :             poSRS->Reference();
     638             :         else
     639           0 :             nSRSId = 0;
     640             :     }
     641             : 
     642           0 :     return poSRS;
     643             : }
     644             : 
     645             : /************************************************************************/
     646             : /*                            GetFIDColumn()                            */
     647             : /************************************************************************/
     648             : 
     649           0 : const char *OGRMSSQLSpatialLayer::GetFIDColumn()
     650             : 
     651             : {
     652           0 :     GetLayerDefn();
     653             : 
     654           0 :     if (pszFIDColumn != nullptr)
     655           0 :         return pszFIDColumn;
     656             :     else
     657           0 :         return "";
     658             : }
     659             : 
     660             : /************************************************************************/
     661             : /*                         GetGeometryColumn()                          */
     662             : /************************************************************************/
     663             : 
     664           0 : const char *OGRMSSQLSpatialLayer::GetGeometryColumn()
     665             : 
     666             : {
     667           0 :     GetLayerDefn();
     668             : 
     669           0 :     if (pszGeomColumn != nullptr)
     670           0 :         return pszGeomColumn;
     671             :     else
     672           0 :         return "";
     673             : }
     674             : 
     675             : /************************************************************************/
     676             : /*                        GByteArrayToHexString()                       */
     677             : /************************************************************************/
     678             : 
     679           0 : char *OGRMSSQLSpatialLayer::GByteArrayToHexString(const GByte *pabyData,
     680             :                                                   int nLen)
     681             : {
     682             :     char *pszTextBuf;
     683             : 
     684           0 :     const size_t nTextBufLen = nLen * 2 + 3;
     685           0 :     pszTextBuf = (char *)CPLMalloc(nTextBufLen);
     686             : 
     687           0 :     int iSrc, iDst = 0;
     688             : 
     689           0 :     for (iSrc = 0; iSrc < nLen; iSrc++)
     690             :     {
     691           0 :         if (iSrc == 0)
     692             :         {
     693           0 :             snprintf(pszTextBuf + iDst, nTextBufLen - iDst, "0x%02x",
     694           0 :                      pabyData[iSrc]);
     695           0 :             iDst += 4;
     696             :         }
     697             :         else
     698             :         {
     699           0 :             snprintf(pszTextBuf + iDst, nTextBufLen - iDst, "%02x",
     700           0 :                      pabyData[iSrc]);
     701           0 :             iDst += 2;
     702             :         }
     703             :     }
     704           0 :     pszTextBuf[iDst] = 0;
     705             : 
     706           0 :     return pszTextBuf;
     707             : }
     708             : 
     709             : /************************************************************************/
     710             : /*                             GetDataset()                             */
     711             : /************************************************************************/
     712             : 
     713           0 : GDALDataset *OGRMSSQLSpatialLayer::GetDataset()
     714             : {
     715           0 :     return poDS;
     716             : }

Generated by: LCOV version 1.14