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

Generated by: LCOV version 1.14