LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/odbc - ogrodbclayer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 123 0 0.0 %
Date: 2012-12-26 Functions: 12 0 0.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrodbclayer.cpp 17755 2009-10-04 21:04:10Z rouault $
       3                 :  *
       4                 :  * Project:  OpenGIS Simple Features Reference Implementation
       5                 :  * Purpose:  Implements OGRODBCLayer class, code shared between 
       6                 :  *           the direct table access, and the generic SQL results.
       7                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       8                 :  *
       9                 :  ******************************************************************************
      10                 :  * Copyright (c) 2003, Frank Warmerdam <warmerdam@pobox.com>
      11                 :  *
      12                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      13                 :  * copy of this software and associated documentation files (the "Software"),
      14                 :  * to deal in the Software without restriction, including without limitation
      15                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      16                 :  * and/or sell copies of the Software, and to permit persons to whom the
      17                 :  * Software is furnished to do so, subject to the following conditions:
      18                 :  *
      19                 :  * The above copyright notice and this permission notice shall be included
      20                 :  * in all copies or substantial portions of the Software.
      21                 :  *
      22                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      23                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      24                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      25                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      26                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      27                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      28                 :  * DEALINGS IN THE SOFTWARE.
      29                 :  ****************************************************************************/
      30                 : 
      31                 : #include "cpl_conv.h"
      32                 : #include "ogr_odbc.h"
      33                 : #include "cpl_string.h"
      34                 : 
      35                 : CPL_CVSID("$Id: ogrodbclayer.cpp 17755 2009-10-04 21:04:10Z rouault $");
      36                 : 
      37                 : /************************************************************************/
      38                 : /*                            OGRODBCLayer()                            */
      39                 : /************************************************************************/
      40                 : 
      41               0 : OGRODBCLayer::OGRODBCLayer()
      42                 : 
      43                 : {
      44               0 :     poDS = NULL;
      45                 : 
      46               0 :     bGeomColumnWKB = FALSE;
      47               0 :     pszGeomColumn = NULL;
      48               0 :     pszFIDColumn = NULL;
      49               0 :     panFieldOrdinals = NULL;
      50                 : 
      51               0 :     poStmt = NULL;
      52                 : 
      53               0 :     iNextShapeId = 0;
      54                 : 
      55               0 :     poSRS = NULL;
      56               0 :     nSRSId = -2; // we haven't even queried the database for it yet. 
      57               0 : }
      58                 : 
      59                 : /************************************************************************/
      60                 : /*                            ~OGRODBCLayer()                             */
      61                 : /************************************************************************/
      62                 : 
      63               0 : OGRODBCLayer::~OGRODBCLayer()
      64                 : 
      65                 : {
      66               0 :     if( m_nFeaturesRead > 0 && poFeatureDefn != NULL )
      67                 :     {
      68                 :         CPLDebug( "OGR_ODBC", "%d features read on layer '%s'.",
      69                 :                   (int) m_nFeaturesRead, 
      70               0 :                   poFeatureDefn->GetName() );
      71                 :     }
      72                 : 
      73               0 :     if( poStmt )
      74                 :     {
      75               0 :         delete poStmt;
      76               0 :         poStmt = NULL;
      77                 :     }
      78                 : 
      79               0 :     if( pszGeomColumn )
      80               0 :         CPLFree( pszGeomColumn );
      81                 : 
      82               0 :     if ( panFieldOrdinals )
      83               0 :         CPLFree( panFieldOrdinals );
      84                 : 
      85               0 :     if( poFeatureDefn )
      86                 :     {
      87               0 :         poFeatureDefn->Release();
      88               0 :         poFeatureDefn = NULL;
      89                 :     }
      90                 : 
      91               0 :     if( poSRS )
      92               0 :         poSRS->Release();
      93               0 : }
      94                 : 
      95                 : /************************************************************************/
      96                 : /*                          BuildFeatureDefn()                          */
      97                 : /*                                                                      */
      98                 : /*      Build feature definition from a set of column definitions       */
      99                 : /*      set on a statement.  Sift out geometry and FID fields.          */
     100                 : /************************************************************************/
     101                 : 
     102               0 : CPLErr OGRODBCLayer::BuildFeatureDefn( const char *pszLayerName, 
     103                 :                                     CPLODBCStatement *poStmt )
     104                 : 
     105                 : {
     106               0 :     poFeatureDefn = new OGRFeatureDefn( pszLayerName );
     107               0 :     int    nRawColumns = poStmt->GetColCount();
     108                 : 
     109               0 :     poFeatureDefn->Reference();
     110                 : 
     111               0 :     panFieldOrdinals = (int *) CPLMalloc( sizeof(int) * nRawColumns );
     112                 : 
     113               0 :     for( int iCol = 0; iCol < nRawColumns; iCol++ )
     114                 :     {
     115               0 :         OGRFieldDefn    oField( poStmt->GetColName(iCol), OFTString );
     116                 : 
     117               0 :         oField.SetWidth( MAX(0,poStmt->GetColSize( iCol )) );
     118                 : 
     119               0 :         if( pszGeomColumn != NULL 
     120                 :             && EQUAL(poStmt->GetColName(iCol),pszGeomColumn) )
     121               0 :             continue;
     122                 : 
     123               0 :         switch( CPLODBCStatement::GetTypeMapping(poStmt->GetColType(iCol)) )
     124                 :         {
     125                 :             case SQL_C_SSHORT:
     126                 :             case SQL_C_USHORT:
     127                 :             case SQL_C_SLONG:
     128                 :             case SQL_C_ULONG:
     129               0 :                 oField.SetType( OFTInteger );
     130               0 :                 break;
     131                 : 
     132                 :             case SQL_C_BINARY:
     133               0 :                 oField.SetType( OFTBinary );
     134               0 :                 break;
     135                 : 
     136                 :             case SQL_C_NUMERIC:
     137               0 :                 oField.SetType( OFTReal );
     138               0 :                 oField.SetPrecision( poStmt->GetColPrecision(iCol) );
     139               0 :                 break;
     140                 : 
     141                 :             case SQL_C_FLOAT:
     142                 :             case SQL_C_DOUBLE:
     143               0 :                 oField.SetType( OFTReal );
     144               0 :                 oField.SetWidth( 0 );
     145               0 :                 break;
     146                 : 
     147                 :             case SQL_C_DATE:
     148               0 :                 oField.SetType( OFTDate );
     149               0 :                 break;
     150                 : 
     151                 :             case SQL_C_TIME:
     152               0 :                 oField.SetType( OFTTime );
     153               0 :                 break;
     154                 : 
     155                 :             case SQL_C_TIMESTAMP:
     156               0 :                 oField.SetType( OFTDateTime );
     157                 :                 break;
     158                 : 
     159                 :             default:
     160                 :                 /* leave it as OFTString */;
     161                 :         }
     162                 : 
     163               0 :         poFeatureDefn->AddFieldDefn( &oField );
     164               0 :         panFieldOrdinals[poFeatureDefn->GetFieldCount() - 1] = iCol+1;
     165                 :     }
     166                 : 
     167                 : /* -------------------------------------------------------------------- */
     168                 : /*      If we don't already have an FID, check if there is a special    */
     169                 : /*      FID named column available.                                     */
     170                 : /* -------------------------------------------------------------------- */
     171               0 :     if( pszFIDColumn == NULL )
     172                 :     {
     173               0 :         const char *pszOGR_FID = CPLGetConfigOption("ODBC_OGR_FID","OGR_FID");
     174               0 :         if( poFeatureDefn->GetFieldIndex( pszOGR_FID ) != -1 )
     175               0 :             pszFIDColumn = CPLStrdup(pszOGR_FID);
     176                 :     }
     177                 : 
     178               0 :     if( pszFIDColumn != NULL )
     179                 :         CPLDebug( "OGR_ODBC", "Using column %s as FID for table %s.",
     180               0 :                   pszFIDColumn, poFeatureDefn->GetName() );
     181                 :     else
     182                 :         CPLDebug( "OGR_ODBC", "Table %s has no identified FID column.",
     183               0 :                   poFeatureDefn->GetName() );
     184                 : 
     185               0 :     return CE_None;
     186                 : }
     187                 : 
     188                 : 
     189                 : /************************************************************************/
     190                 : /*                            ResetReading()                            */
     191                 : /************************************************************************/
     192                 : 
     193               0 : void OGRODBCLayer::ResetReading()
     194                 : 
     195                 : {
     196               0 :     iNextShapeId = 0;
     197               0 : }
     198                 : 
     199                 : /************************************************************************/
     200                 : /*                           GetNextFeature()                           */
     201                 : /************************************************************************/
     202                 : 
     203               0 : OGRFeature *OGRODBCLayer::GetNextFeature()
     204                 : 
     205                 : {
     206               0 :     for( ; TRUE; )
     207                 :     {
     208                 :         OGRFeature      *poFeature;
     209                 : 
     210               0 :         poFeature = GetNextRawFeature();
     211               0 :         if( poFeature == NULL )
     212               0 :             return NULL;
     213                 : 
     214               0 :         if( (m_poFilterGeom == NULL
     215                 :             || FilterGeometry( poFeature->GetGeometryRef() ) )
     216                 :             && (m_poAttrQuery == NULL
     217                 :                 || m_poAttrQuery->Evaluate( poFeature )) )
     218               0 :             return poFeature;
     219                 : 
     220               0 :         delete poFeature;
     221                 :     }
     222                 : }
     223                 : 
     224                 : /************************************************************************/
     225                 : /*                         GetNextRawFeature()                          */
     226                 : /************************************************************************/
     227                 : 
     228               0 : OGRFeature *OGRODBCLayer::GetNextRawFeature()
     229                 : 
     230                 : {
     231               0 :     if( GetStatement() == NULL )
     232               0 :         return NULL;
     233                 : 
     234                 : /* -------------------------------------------------------------------- */
     235                 : /*      If we are marked to restart then do so, and fetch a record.     */
     236                 : /* -------------------------------------------------------------------- */
     237               0 :     if( !poStmt->Fetch() )
     238                 :     {
     239               0 :         delete poStmt;
     240               0 :         poStmt = NULL;
     241               0 :         return NULL;
     242                 :     }
     243                 : 
     244                 : /* -------------------------------------------------------------------- */
     245                 : /*      Create a feature from the current result.                       */
     246                 : /* -------------------------------------------------------------------- */
     247                 :     int         iField;
     248               0 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
     249                 : 
     250               0 :     if( pszFIDColumn != NULL && poStmt->GetColId(pszFIDColumn) > -1 )
     251                 :         poFeature->SetFID( 
     252               0 :             atoi(poStmt->GetColData(poStmt->GetColId(pszFIDColumn))) );
     253                 :     else
     254               0 :         poFeature->SetFID( iNextShapeId );
     255                 : 
     256               0 :     iNextShapeId++;
     257               0 :     m_nFeaturesRead++;
     258                 : 
     259                 : /* -------------------------------------------------------------------- */
     260                 : /*      Set the fields.                                                 */
     261                 : /* -------------------------------------------------------------------- */
     262               0 :     for( iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ )
     263                 :     {
     264               0 :         int iSrcField = panFieldOrdinals[iField]-1;
     265               0 :         const char *pszValue = poStmt->GetColData( iSrcField );
     266                 : 
     267               0 :         if( pszValue == NULL )
     268                 :             /* no value */;
     269               0 :         else if( poFeature->GetFieldDefnRef(iField)->GetType() == OFTBinary )
     270                 :             poFeature->SetField( iField, 
     271                 :                                  poStmt->GetColDataLength(iSrcField),
     272               0 :                                  (GByte *) pszValue );
     273                 :         else
     274               0 :             poFeature->SetField( iField, pszValue );
     275                 :     }
     276                 : 
     277                 : /* -------------------------------------------------------------------- */
     278                 : /*      Try to extract a geometry.                                      */
     279                 : /* -------------------------------------------------------------------- */
     280               0 :     if( pszGeomColumn != NULL )
     281                 :     {
     282               0 :         int iField = poStmt->GetColId( pszGeomColumn );
     283               0 :         const char *pszGeomText = poStmt->GetColData( iField );
     284               0 :         OGRGeometry *poGeom = NULL;
     285               0 :         OGRErr eErr = OGRERR_NONE;
     286                 : 
     287               0 :         if( pszGeomText != NULL && !bGeomColumnWKB )
     288                 :         {
     289                 :             eErr =
     290                 :                 OGRGeometryFactory::createFromWkt((char **) &pszGeomText,
     291               0 :                                                   NULL, &poGeom);
     292                 :         }
     293               0 :         else if( pszGeomText != NULL && bGeomColumnWKB )
     294                 :         {
     295               0 :             int nLength = poStmt->GetColDataLength( iField );
     296                 : 
     297                 :             eErr =
     298                 :                 OGRGeometryFactory::createFromWkb((unsigned char *) pszGeomText,
     299               0 :                                                   NULL, &poGeom, nLength);
     300                 :         }
     301                 :         
     302               0 :         if ( eErr != OGRERR_NONE )
     303                 :         {
     304                 :             const char *pszMessage;
     305                 : 
     306               0 :             switch ( eErr )
     307                 :             {
     308                 :                 case OGRERR_NOT_ENOUGH_DATA:
     309               0 :                     pszMessage = "Not enough data to deserialize";
     310               0 :                     break;
     311                 :                 case OGRERR_UNSUPPORTED_GEOMETRY_TYPE:
     312               0 :                     pszMessage = "Unsupported geometry type";
     313               0 :                     break;
     314                 :                 case OGRERR_CORRUPT_DATA:
     315               0 :                     pszMessage = "Corrupt data";
     316               0 :                     break;
     317                 :                 default:
     318               0 :                     pszMessage = "Unrecognized error";
     319                 :             }
     320                 :             CPLError(CE_Failure, CPLE_AppDefined,
     321               0 :                      "GetNextRawFeature(): %s", pszMessage);
     322                 :         }
     323                 : 
     324               0 :         if( poGeom != NULL )
     325               0 :             poFeature->SetGeometryDirectly( poGeom );
     326                 :     }
     327                 : 
     328               0 :     return poFeature;
     329                 : }
     330                 : 
     331                 : /************************************************************************/
     332                 : /*                             GetFeature()                             */
     333                 : /************************************************************************/
     334                 : 
     335               0 : OGRFeature *OGRODBCLayer::GetFeature( long nFeatureId )
     336                 : 
     337                 : {
     338                 :     /* This should be implemented directly! */
     339                 : 
     340               0 :     return OGRLayer::GetFeature( nFeatureId );
     341                 : }
     342                 : 
     343                 : /************************************************************************/
     344                 : /*                           TestCapability()                           */
     345                 : /************************************************************************/
     346                 : 
     347               0 : int OGRODBCLayer::TestCapability( const char * pszCap )
     348                 : 
     349                 : {
     350               0 :     return FALSE;
     351                 : }
     352                 : 
     353                 : /************************************************************************/
     354                 : /*                           GetSpatialRef()                            */
     355                 : /************************************************************************/
     356                 : 
     357               0 : OGRSpatialReference *OGRODBCLayer::GetSpatialRef()
     358                 : 
     359                 : {
     360               0 :     return poSRS;
     361                 : }
     362                 : 

Generated by: LCOV version 1.7