LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/mssqlspatial - ogrmssqlspatiallayer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 183 0 0.0 %
Date: 2012-04-28 Functions: 18 0 0.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrmssqlspatiallayer.cpp 24330 2012-04-28 11:46:49Z tamas $
       3                 :  *
       4                 :  * Project:  MSSQL Spatial driver
       5                 :  * Purpose:  Definition of classes for OGR MSSQL Spatial driver.
       6                 :  * Author:   Tamas Szekeres, szekerest at gmail.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2010, Tamas Szekeres
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "ogr_mssqlspatial.h"
      31                 : 
      32                 : CPL_CVSID("$Id: ogrmssqlspatiallayer.cpp 24330 2012-04-28 11:46:49Z tamas $");
      33                 : /************************************************************************/
      34                 : /*                        OGRMSSQLSpatialLayer()                        */
      35                 : /************************************************************************/
      36                 : 
      37               0 : OGRMSSQLSpatialLayer::OGRMSSQLSpatialLayer()
      38                 : 
      39                 : {
      40               0 :     poDS = NULL;
      41                 : 
      42               0 :     nGeomColumnType = -1;
      43               0 :     pszGeomColumn = NULL;
      44               0 :     pszFIDColumn = NULL;
      45               0 :     panFieldOrdinals = NULL;
      46                 : 
      47               0 :     poStmt = NULL;
      48                 : 
      49               0 :     iNextShapeId = 0;
      50                 : 
      51               0 :     poSRS = NULL;
      52               0 :     nSRSId = -1; // we haven't even queried the database for it yet. 
      53               0 : }
      54                 : 
      55                 : /************************************************************************/
      56                 : /*                      ~OGRMSSQLSpatialLayer()                         */
      57                 : /************************************************************************/
      58                 : 
      59               0 : OGRMSSQLSpatialLayer::~OGRMSSQLSpatialLayer()
      60                 : 
      61                 : {
      62               0 :     if( m_nFeaturesRead > 0 && poFeatureDefn != NULL )
      63                 :     {
      64                 :         CPLDebug( "OGR_MSSQLSpatial", "%d features read on layer '%s'.",
      65                 :                   (int) m_nFeaturesRead, 
      66               0 :                   poFeatureDefn->GetName() );
      67                 :     }
      68                 : 
      69               0 :     if( poStmt )
      70                 :     {
      71               0 :         delete poStmt;
      72               0 :         poStmt = NULL;
      73                 :     }
      74                 : 
      75               0 :     CPLFree( pszGeomColumn );
      76               0 :     CPLFree( pszFIDColumn );
      77               0 :     CPLFree( panFieldOrdinals );
      78                 : 
      79               0 :     if( poFeatureDefn )
      80                 :     {
      81               0 :         poFeatureDefn->Release();
      82               0 :         poFeatureDefn = NULL;
      83                 :     }
      84                 : 
      85               0 :     if( poSRS )
      86               0 :         poSRS->Release();
      87               0 : }
      88                 : 
      89                 : /************************************************************************/
      90                 : /*                          BuildFeatureDefn()                          */
      91                 : /*                                                                      */
      92                 : /*      Build feature definition from a set of column definitions       */
      93                 : /*      set on a statement.  Sift out geometry and FID fields.          */
      94                 : /************************************************************************/
      95                 : 
      96               0 : CPLErr OGRMSSQLSpatialLayer::BuildFeatureDefn( const char *pszLayerName, 
      97                 :                                     CPLODBCStatement *poStmt )
      98                 : 
      99                 : {
     100               0 :     poFeatureDefn = new OGRFeatureDefn( pszLayerName );
     101               0 :     int    nRawColumns = poStmt->GetColCount();
     102                 : 
     103               0 :     poFeatureDefn->Reference();
     104                 : 
     105               0 :     CPLFree(panFieldOrdinals);
     106               0 :     panFieldOrdinals = (int *) CPLMalloc( sizeof(int) * nRawColumns );
     107                 : 
     108               0 :     for( int iCol = 0; iCol < nRawColumns; iCol++ )
     109                 :     {
     110               0 :         if ( pszGeomColumn == NULL )
     111                 :         {
     112                 :             /* need to identify the geometry column */
     113               0 :             if ( EQUAL(poStmt->GetColTypeName( iCol ), "geometry") )
     114                 :             {
     115               0 :                 nGeomColumnType = MSSQLCOLTYPE_GEOMETRY;
     116               0 :                 pszGeomColumn = CPLStrdup( poStmt->GetColName(iCol) );
     117               0 :                 continue;
     118                 :             }
     119               0 :             else if ( EQUAL(poStmt->GetColTypeName( iCol ), "geography") )
     120                 :             {
     121               0 :                 nGeomColumnType = MSSQLCOLTYPE_GEOGRAPHY;
     122               0 :                 pszGeomColumn = CPLStrdup( poStmt->GetColName(iCol) );
     123               0 :                 continue;
     124                 :             }
     125               0 :             else if ( EQUAL(poStmt->GetColTypeName( iCol ), "image") )
     126                 :             {
     127                 :                 /* for the select layers we get image type */
     128               0 :                 nGeomColumnType = MSSQLCOLTYPE_BINARY;
     129               0 :                 pszGeomColumn = CPLStrdup( poStmt->GetColName(iCol) );
     130               0 :                 continue;
     131                 :             }
     132                 :         }
     133                 :         else
     134                 :         {
     135               0 :             if( EQUAL(poStmt->GetColName(iCol),pszGeomColumn) )
     136               0 :                 continue;
     137                 :         }
     138                 : 
     139               0 :         if( pszFIDColumn != NULL &&
     140                 :         EQUAL(poStmt->GetColName(iCol), pszFIDColumn) )
     141                 :         {
     142                 :             /* skip FID */
     143               0 :             continue;
     144                 :         }
     145                 : 
     146               0 :         OGRFieldDefn    oField( poStmt->GetColName(iCol), OFTString );
     147               0 :         oField.SetWidth( MAX(0,poStmt->GetColSize( iCol )) );
     148                 : 
     149               0 :         switch( CPLODBCStatement::GetTypeMapping(poStmt->GetColType(iCol)) )
     150                 :         {
     151                 :             case SQL_C_SSHORT:
     152                 :             case SQL_C_USHORT:
     153                 :             case SQL_C_SLONG:
     154                 :             case SQL_C_ULONG:
     155               0 :                 oField.SetType( OFTInteger );
     156               0 :                 break;
     157                 : 
     158                 :             case SQL_C_BINARY:
     159               0 :                 oField.SetType( OFTBinary );
     160               0 :                 break;
     161                 : 
     162                 :             case SQL_C_NUMERIC:
     163               0 :                 oField.SetType( OFTReal );
     164               0 :                 oField.SetPrecision( poStmt->GetColPrecision(iCol) );
     165               0 :                 break;
     166                 : 
     167                 :             case SQL_C_FLOAT:
     168                 :             case SQL_C_DOUBLE:
     169               0 :                 oField.SetType( OFTReal );
     170               0 :                 oField.SetWidth( 0 );
     171               0 :                 break;
     172                 : 
     173                 :             case SQL_C_DATE:
     174               0 :                 oField.SetType( OFTDate );
     175               0 :                 break;
     176                 : 
     177                 :             case SQL_C_TIME:
     178               0 :                 oField.SetType( OFTTime );
     179               0 :                 break;
     180                 : 
     181                 :             case SQL_C_TIMESTAMP:
     182               0 :                 oField.SetType( OFTDateTime );
     183                 :                 break;
     184                 : 
     185                 :             default:
     186                 :                 /* leave it as OFTString */;
     187                 :         }
     188                 : 
     189               0 :         poFeatureDefn->AddFieldDefn( &oField );
     190               0 :         panFieldOrdinals[poFeatureDefn->GetFieldCount() - 1] = iCol;
     191                 :     }
     192                 : 
     193                 : /* -------------------------------------------------------------------- */
     194                 : /*      If we don't already have an FID, check if there is a special    */
     195                 : /*      FID named column available.                                     */
     196                 : /* -------------------------------------------------------------------- */
     197               0 :     if( pszFIDColumn == NULL )
     198                 :     {
     199               0 :         const char *pszOGR_FID = CPLGetConfigOption("MSSQLSPATIAL_OGR_FID","OGR_FID");
     200               0 :         if( poFeatureDefn->GetFieldIndex( pszOGR_FID ) != -1 )
     201               0 :             pszFIDColumn = CPLStrdup(pszOGR_FID);
     202                 :     }
     203                 : 
     204               0 :     if( pszFIDColumn != NULL )
     205                 :         CPLDebug( "OGR_MSSQLSpatial", "Using column %s as FID for table %s.",
     206               0 :                   pszFIDColumn, poFeatureDefn->GetName() );
     207                 :     else
     208                 :         CPLDebug( "OGR_MSSQLSpatial", "Table %s has no identified FID column.",
     209               0 :                   poFeatureDefn->GetName() );
     210                 : 
     211               0 :     return CE_None;
     212                 : }
     213                 : 
     214                 : 
     215                 : /************************************************************************/
     216                 : /*                            ResetReading()                            */
     217                 : /************************************************************************/
     218                 : 
     219               0 : void OGRMSSQLSpatialLayer::ResetReading()
     220                 : 
     221                 : {
     222               0 :     iNextShapeId = 0;
     223               0 : }
     224                 : 
     225                 : /************************************************************************/
     226                 : /*                           GetNextFeature()                           */
     227                 : /************************************************************************/
     228                 : 
     229               0 : OGRFeature *OGRMSSQLSpatialLayer::GetNextFeature()
     230                 : 
     231                 : {
     232               0 :     while( TRUE )
     233                 :     {
     234                 :         OGRFeature      *poFeature;
     235                 : 
     236               0 :         poFeature = GetNextRawFeature();
     237               0 :         if( poFeature == NULL )
     238               0 :             return NULL;
     239                 : 
     240               0 :         if( (m_poFilterGeom == NULL
     241                 :             || FilterGeometry( poFeature->GetGeometryRef() ) )
     242                 :             && (m_poAttrQuery == NULL
     243                 :                 || m_poAttrQuery->Evaluate( poFeature )) )
     244               0 :             return poFeature;
     245                 : 
     246               0 :         delete poFeature;
     247                 :     }
     248                 : }
     249                 : 
     250                 : /************************************************************************/
     251                 : /*                         GetNextRawFeature()                          */
     252                 : /************************************************************************/
     253                 : 
     254               0 : OGRFeature *OGRMSSQLSpatialLayer::GetNextRawFeature()
     255                 : 
     256                 : {
     257               0 :     if( GetStatement() == NULL )
     258               0 :         return NULL;
     259                 : 
     260                 : /* -------------------------------------------------------------------- */
     261                 : /*      If we are marked to restart then do so, and fetch a record.     */
     262                 : /* -------------------------------------------------------------------- */
     263               0 :     if( !poStmt->Fetch() )
     264                 :     {
     265               0 :         delete poStmt;
     266               0 :         poStmt = NULL;
     267               0 :         return NULL;
     268                 :     }
     269                 : 
     270                 : /* -------------------------------------------------------------------- */
     271                 : /*      Create a feature from the current result.                       */
     272                 : /* -------------------------------------------------------------------- */
     273                 :     int         iField;
     274               0 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
     275                 : 
     276               0 :     if( pszFIDColumn != NULL && poStmt->GetColId(pszFIDColumn) > -1 )
     277                 :         poFeature->SetFID( 
     278               0 :             atoi(poStmt->GetColData(poStmt->GetColId(pszFIDColumn))) );
     279                 :     else
     280               0 :         poFeature->SetFID( iNextShapeId );
     281                 : 
     282               0 :     iNextShapeId++;
     283               0 :     m_nFeaturesRead++;
     284                 : 
     285                 : /* -------------------------------------------------------------------- */
     286                 : /*      Set the fields.                                                 */
     287                 : /* -------------------------------------------------------------------- */
     288               0 :     for( iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ )
     289                 :     {
     290               0 :         int iSrcField = panFieldOrdinals[iField];
     291               0 :         const char *pszValue = poStmt->GetColData( iSrcField );
     292                 : 
     293               0 :         if( pszValue == NULL )
     294                 :             /* no value */;
     295               0 :         else if( poFeature->GetFieldDefnRef(iField)->GetType() == OFTBinary )
     296                 :             poFeature->SetField( iField, 
     297                 :                                  poStmt->GetColDataLength(iSrcField),
     298               0 :                                  (GByte *) pszValue );
     299                 :         else
     300               0 :             poFeature->SetField( iField, pszValue );
     301                 :     }
     302                 : 
     303                 : /* -------------------------------------------------------------------- */
     304                 : /*      Try to extract a geometry.                                      */
     305                 : /* -------------------------------------------------------------------- */
     306               0 :     if( pszGeomColumn != NULL )
     307                 :     {
     308               0 :         int iField = poStmt->GetColId( pszGeomColumn );
     309               0 :         const char *pszGeomText = poStmt->GetColData( iField );
     310               0 :         OGRGeometry *poGeom = NULL;
     311               0 :         OGRErr eErr = OGRERR_NONE;
     312                 : 
     313               0 :         if( pszGeomText != NULL )
     314                 :         {
     315               0 :             int nLength = poStmt->GetColDataLength( iField );
     316                 : 
     317               0 :             if ( nGeomColumnType == MSSQLCOLTYPE_GEOMETRY || 
     318                 :                  nGeomColumnType == MSSQLCOLTYPE_GEOGRAPHY ||
     319                 :                  nGeomColumnType == MSSQLCOLTYPE_BINARY)
     320                 :             {
     321               0 :                 switch ( poDS->GetGeometryFormat() )
     322                 :                 {
     323                 :                 case MSSQLGEOMETRY_NATIVE:
     324                 :                     {
     325               0 :                         OGRMSSQLGeometryParser oParser( nGeomColumnType ); 
     326                 :                         eErr = oParser.ParseSqlGeometry( 
     327               0 :                             (unsigned char *) pszGeomText, nLength, &poGeom );
     328               0 :                         nSRSId = oParser.GetSRSId();
     329                 :                     }
     330               0 :                     break;
     331                 :                 case MSSQLGEOMETRY_WKB:
     332                 :                     eErr = OGRGeometryFactory::createFromWkb((unsigned char *) pszGeomText,
     333               0 :                                                       NULL, &poGeom, nLength);
     334               0 :                     break;
     335                 :                 case MSSQLGEOMETRY_WKT:
     336                 :                     eErr = OGRGeometryFactory::createFromWkt((char **) &pszGeomText,
     337               0 :                                                       NULL, &poGeom);
     338                 :                     break;
     339                 :                 } 
     340                 :             }
     341               0 :             else if (nGeomColumnType == MSSQLCOLTYPE_TEXT)
     342                 :             {
     343                 :                 eErr = OGRGeometryFactory::createFromWkt((char **) &pszGeomText,
     344               0 :                                                       NULL, &poGeom);
     345                 :             }    
     346                 :         }
     347                 :         
     348               0 :         if ( eErr != OGRERR_NONE )
     349                 :         {
     350                 :             const char *pszMessage;
     351                 : 
     352               0 :             switch ( eErr )
     353                 :             {
     354                 :                 case OGRERR_NOT_ENOUGH_DATA:
     355               0 :                     pszMessage = "Not enough data to deserialize";
     356               0 :                     break;
     357                 :                 case OGRERR_UNSUPPORTED_GEOMETRY_TYPE:
     358               0 :                     pszMessage = "Unsupported geometry type";
     359               0 :                     break;
     360                 :                 case OGRERR_CORRUPT_DATA:
     361               0 :                     pszMessage = "Corrupt data";
     362               0 :                     break;
     363                 :                 default:
     364               0 :                     pszMessage = "Unrecognized error";
     365                 :             }
     366                 :             CPLError(CE_Failure, CPLE_AppDefined,
     367               0 :                      "GetNextRawFeature(): %s", pszMessage);
     368                 :         }
     369                 : 
     370               0 :         if( poGeom != NULL )
     371                 :         {
     372               0 :             if ( GetSpatialRef() )
     373               0 :                 poGeom->assignSpatialReference( poSRS );
     374                 : 
     375               0 :             poFeature->SetGeometryDirectly( poGeom );
     376                 :         }
     377                 :     }
     378                 : 
     379               0 :     return poFeature;
     380                 : }
     381                 : 
     382                 : /************************************************************************/
     383                 : /*                             GetFeature()                             */
     384                 : /************************************************************************/
     385                 : 
     386               0 : OGRFeature *OGRMSSQLSpatialLayer::GetFeature( long nFeatureId )
     387                 : 
     388                 : {
     389                 :     /* This should be implemented directly! */
     390                 : 
     391               0 :     return OGRLayer::GetFeature( nFeatureId );
     392                 : }
     393                 : 
     394                 : /************************************************************************/
     395                 : /*                           TestCapability()                           */
     396                 : /************************************************************************/
     397                 : 
     398               0 : int OGRMSSQLSpatialLayer::TestCapability( const char * pszCap )
     399                 : 
     400                 : {
     401               0 :     return FALSE;
     402                 : }
     403                 : 
     404                 : /************************************************************************/
     405                 : /*                          StartTransaction()                          */
     406                 : /************************************************************************/
     407                 : 
     408               0 : OGRErr OGRMSSQLSpatialLayer::StartTransaction()
     409                 : 
     410                 : {
     411               0 :     poDS->GetSession()->BeginTransaction();
     412               0 :     return OGRERR_NONE;
     413                 : }
     414                 : 
     415                 : /************************************************************************/
     416                 : /*                         CommitTransaction()                          */
     417                 : /************************************************************************/
     418                 : 
     419               0 : OGRErr OGRMSSQLSpatialLayer::CommitTransaction()
     420                 : 
     421                 : {
     422               0 :     poDS->GetSession()->CommitTransaction();
     423               0 :     return OGRERR_NONE;
     424                 : }
     425                 : 
     426                 : /************************************************************************/
     427                 : /*                        RollbackTransaction()                         */
     428                 : /************************************************************************/
     429                 : 
     430               0 : OGRErr OGRMSSQLSpatialLayer::RollbackTransaction()
     431                 : 
     432                 : {
     433               0 :     poDS->GetSession()->RollbackTransaction();
     434               0 :     return OGRERR_NONE;
     435                 : }
     436                 : 
     437                 : /************************************************************************/
     438                 : /*                           GetSpatialRef()                            */
     439                 : /************************************************************************/
     440                 : 
     441               0 : OGRSpatialReference *OGRMSSQLSpatialLayer::GetSpatialRef()
     442                 : 
     443                 : {
     444               0 :     if( poSRS == NULL && nSRSId > 0 )
     445                 :     {
     446               0 :         poSRS = poDS->FetchSRS( nSRSId );
     447               0 :         if( poSRS != NULL )
     448               0 :             poSRS->Reference();
     449                 :         else
     450               0 :             nSRSId = 0;
     451                 :     }
     452                 : 
     453               0 :     return poSRS;
     454                 : }
     455                 : 
     456                 : /************************************************************************/
     457                 : /*                            GetFIDColumn()                            */
     458                 : /************************************************************************/
     459                 : 
     460               0 : const char *OGRMSSQLSpatialLayer::GetFIDColumn() 
     461                 : 
     462                 : {
     463               0 :     GetLayerDefn();
     464                 : 
     465               0 :     if( pszFIDColumn != NULL )
     466               0 :         return pszFIDColumn;
     467                 :     else
     468               0 :         return "";
     469                 : }
     470                 : 
     471                 : /************************************************************************/
     472                 : /*                         GetGeometryColumn()                          */
     473                 : /************************************************************************/
     474                 : 
     475               0 : const char *OGRMSSQLSpatialLayer::GetGeometryColumn() 
     476                 : 
     477                 : {
     478               0 :     GetLayerDefn();
     479                 : 
     480               0 :     if( pszGeomColumn != NULL )
     481               0 :         return pszGeomColumn;
     482                 :     else
     483               0 :         return "";
     484                 : }
     485                 : 
     486                 : /************************************************************************/
     487                 : /*                        GByteArrayToHexString()                       */
     488                 : /************************************************************************/
     489                 : 
     490               0 : char* OGRMSSQLSpatialLayer::GByteArrayToHexString( const GByte* pabyData, int nLen)
     491                 : {
     492                 :     char* pszTextBuf;
     493                 : 
     494               0 :     pszTextBuf = (char *) CPLMalloc(nLen*2+3);
     495                 : 
     496               0 :     int  iSrc, iDst=0;
     497                 : 
     498               0 :     for( iSrc = 0; iSrc < nLen; iSrc++ )
     499                 :     {
     500               0 :         if( iSrc == 0 )
     501                 :         {
     502               0 :             sprintf( pszTextBuf+iDst, "0x%02x", pabyData[iSrc] );
     503               0 :             iDst += 4;
     504                 :         }
     505                 :         else
     506                 :         {
     507               0 :             sprintf( pszTextBuf+iDst, "%02x", pabyData[iSrc] );
     508               0 :             iDst += 2;
     509                 :         }
     510                 :     }
     511               0 :     pszTextBuf[iDst] = 0;
     512                 : 
     513               0 :     return pszTextBuf;
     514                 : }
     515                 : 

Generated by: LCOV version 1.7