LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/mssqlspatial - ogrmssqlspatialselectlayer.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 0 75 0.0 %
Date: 2025-05-31 00:00:17 Functions: 0 7 0.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  MSSQL Spatial driver
       4             :  * Purpose:  Implements OGRMSSQLSpatialSelectLayer class, layer access to the
       5             :  *results of a SELECT statement executed via ExecuteSQL(). Author:   Tamas
       6             :  *Szekeres, szekerest at gmail.com
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 2010, Tamas Szekeres
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #include "cpl_conv.h"
      15             : #include "ogr_mssqlspatial.h"
      16             : 
      17             : // SQL_CA_SS_UDT_TYPE_NAME not defined in unixODBC headers
      18             : #ifndef SQL_CA_SS_BASE
      19             : #define SQL_CA_SS_BASE 1200
      20             : #endif
      21             : 
      22             : #ifndef SQL_CA_SS_UDT_TYPE_NAME
      23             : #define SQL_CA_SS_UDT_TYPE_NAME (SQL_CA_SS_BASE + 20)
      24             : #endif
      25             : 
      26             : /************************************************************************/
      27             : /*                     OGRMSSQLSpatialSelectLayer()                     */
      28             : /************************************************************************/
      29             : 
      30           0 : OGRMSSQLSpatialSelectLayer::OGRMSSQLSpatialSelectLayer(
      31           0 :     OGRMSSQLSpatialDataSource *poDSIn, CPLODBCStatement *poStmtIn)
      32           0 :     : OGRMSSQLSpatialLayer(poDSIn)
      33             : 
      34             : {
      35           0 :     iNextShapeId = 0;
      36           0 :     nSRSId = 0;
      37           0 :     poFeatureDefn = nullptr;
      38             : 
      39           0 :     poStmt = poStmtIn;
      40           0 :     pszBaseStatement = CPLStrdup(poStmtIn->GetCommand());
      41             : 
      42             :     /* identify the geometry column */
      43           0 :     pszGeomColumn = nullptr;
      44           0 :     int iImageCol = -1;
      45           0 :     for (int iColumn = 0; iColumn < poStmt->GetColCount(); iColumn++)
      46             :     {
      47           0 :         if (EQUAL(poStmt->GetColTypeName(iColumn), "image"))
      48             :         {
      49             :             SQLCHAR szTableName[256];
      50           0 :             SQLSMALLINT nTableNameLength = 0;
      51             : 
      52           0 :             SQLColAttribute(poStmt->GetStatement(),
      53           0 :                             static_cast<SQLSMALLINT>(iColumn + 1),
      54             :                             SQL_DESC_TABLE_NAME, szTableName,
      55             :                             sizeof(szTableName), &nTableNameLength, nullptr);
      56             : 
      57           0 :             if (nTableNameLength > 0)
      58             :             {
      59             :                 OGRLayer *poBaseLayer =
      60           0 :                     poDS->GetLayerByName(reinterpret_cast<char *>(szTableName));
      61           0 :                 if (poBaseLayer != nullptr &&
      62           0 :                     EQUAL(poBaseLayer->GetGeometryColumn(),
      63             :                           poStmt->GetColName(iColumn)))
      64             :                 {
      65           0 :                     nGeomColumnType = MSSQLCOLTYPE_BINARY;
      66           0 :                     pszGeomColumn = CPLStrdup(poStmt->GetColName(iColumn));
      67             :                     /* copy spatial reference */
      68           0 :                     if (!poSRS && poBaseLayer->GetSpatialRef())
      69           0 :                         poSRS = poBaseLayer->GetSpatialRef()->Clone();
      70           0 :                     break;
      71             :                 }
      72             :             }
      73           0 :             else if (iImageCol == -1)
      74           0 :                 iImageCol = iColumn;
      75             :         }
      76           0 :         else if (EQUAL(poStmt->GetColTypeName(iColumn), "geometry"))
      77             :         {
      78           0 :             nGeomColumnType = MSSQLCOLTYPE_GEOMETRY;
      79           0 :             pszGeomColumn = CPLStrdup(poStmt->GetColName(iColumn));
      80           0 :             break;
      81             :         }
      82           0 :         else if (EQUAL(poStmt->GetColTypeName(iColumn), "geography"))
      83             :         {
      84           0 :             nGeomColumnType = MSSQLCOLTYPE_GEOGRAPHY;
      85           0 :             pszGeomColumn = CPLStrdup(poStmt->GetColName(iColumn));
      86           0 :             break;
      87             :         }
      88           0 :         else if (EQUAL(poStmt->GetColTypeName(iColumn), "udt"))
      89             :         {
      90             :             SQLCHAR szUDTTypeName[256];
      91           0 :             SQLSMALLINT nUDTTypeNameLength = 0;
      92             : 
      93           0 :             SQLColAttribute(
      94           0 :                 poStmt->GetStatement(), static_cast<SQLSMALLINT>(iColumn + 1),
      95             :                 SQL_CA_SS_UDT_TYPE_NAME, szUDTTypeName, sizeof(szUDTTypeName),
      96             :                 &nUDTTypeNameLength, nullptr);
      97             : 
      98             :             // For some reason on unixODBC, a UCS2 string is returned
      99           0 :             if (EQUAL(reinterpret_cast<char *>(szUDTTypeName), "geometry") ||
     100           0 :                 (nUDTTypeNameLength == 16 &&
     101           0 :                  memcmp(szUDTTypeName, "g\0e\0o\0m\0e\0t\0r\0y", 16) == 0))
     102             :             {
     103           0 :                 nGeomColumnType = MSSQLCOLTYPE_GEOMETRY;
     104           0 :                 pszGeomColumn = CPLStrdup(poStmt->GetColName(iColumn));
     105             :             }
     106           0 :             else if (EQUAL(reinterpret_cast<char *>(szUDTTypeName),
     107           0 :                            "geography") ||
     108           0 :                      (nUDTTypeNameLength == 18 &&
     109           0 :                       memcmp(szUDTTypeName, "g\0e\0o\0g\0r\0a\0p\0h\0y", 18) ==
     110             :                           0))
     111             :             {
     112           0 :                 nGeomColumnType = MSSQLCOLTYPE_GEOGRAPHY;
     113           0 :                 pszGeomColumn = CPLStrdup(poStmt->GetColName(iColumn));
     114             :             }
     115           0 :             break;
     116             :         }
     117             :     }
     118             : 
     119           0 :     if (pszGeomColumn == nullptr && iImageCol >= 0)
     120             :     {
     121             :         /* set the image col as geometry column as the last resort */
     122           0 :         nGeomColumnType = MSSQLCOLTYPE_BINARY;
     123           0 :         pszGeomColumn = CPLStrdup(poStmt->GetColName(iImageCol));
     124             :     }
     125             : 
     126           0 :     BuildFeatureDefn("SELECT", poStmt);
     127             : 
     128           0 :     if (GetSpatialRef() && poFeatureDefn->GetGeomFieldCount() == 1)
     129           0 :         poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poSRS);
     130           0 : }
     131             : 
     132             : /************************************************************************/
     133             : /*                    ~OGRMSSQLSpatialSelectLayer()                     */
     134             : /************************************************************************/
     135             : 
     136           0 : OGRMSSQLSpatialSelectLayer::~OGRMSSQLSpatialSelectLayer()
     137             : 
     138             : {
     139           0 :     CPLFree(pszBaseStatement);
     140           0 : }
     141             : 
     142             : /************************************************************************/
     143             : /*                            GetStatement()                            */
     144             : /************************************************************************/
     145             : 
     146           0 : CPLODBCStatement *OGRMSSQLSpatialSelectLayer::GetStatement()
     147             : 
     148             : {
     149           0 :     if (poStmt == nullptr)
     150             :     {
     151           0 :         CPLDebug("OGR_MSSQLSpatial", "Recreating statement.");
     152           0 :         poStmt = new CPLODBCStatement(poDS->GetSession());
     153           0 :         poStmt->Append(pszBaseStatement);
     154             : 
     155           0 :         if (!poStmt->ExecuteSQL())
     156             :         {
     157           0 :             delete poStmt;
     158           0 :             poStmt = nullptr;
     159             :         }
     160             :     }
     161             : 
     162           0 :     return poStmt;
     163             : }
     164             : 
     165             : /************************************************************************/
     166             : /*                             GetFeature()                             */
     167             : /************************************************************************/
     168             : 
     169           0 : OGRFeature *OGRMSSQLSpatialSelectLayer::GetFeature(GIntBig nFeatureId)
     170             : 
     171             : {
     172           0 :     return OGRMSSQLSpatialLayer::GetFeature(nFeatureId);
     173             : }
     174             : 
     175             : /************************************************************************/
     176             : /*                           TestCapability()                           */
     177             : /************************************************************************/
     178             : 
     179           0 : int OGRMSSQLSpatialSelectLayer::TestCapability(const char *pszCap)
     180             : 
     181             : {
     182           0 :     return OGRMSSQLSpatialLayer::TestCapability(pszCap);
     183             : }
     184             : 
     185             : /************************************************************************/
     186             : /*                          GetFeatureCount()                           */
     187             : /*                                                                      */
     188             : /*      If a spatial filter is in effect, we turn control over to       */
     189             : /*      the generic counter.  Otherwise we return the total count.      */
     190             : /*      Eventually we should consider implementing a more efficient     */
     191             : /*      way of counting features matching a spatial query.              */
     192             : /************************************************************************/
     193             : 
     194           0 : GIntBig OGRMSSQLSpatialSelectLayer::GetFeatureCount(int bForce)
     195             : 
     196             : {
     197           0 :     return OGRMSSQLSpatialLayer::GetFeatureCount(bForce);
     198             : }

Generated by: LCOV version 1.14