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

       1                 : /******************************************************************************
       2                 :  * $Id: ogrodbctablelayer.cpp 24961 2012-09-23 18:06:49Z rouault $
       3                 :  *
       4                 :  * Project:  OpenGIS Simple Features Reference Implementation
       5                 :  * Purpose:  Implements OGRODBCTableLayer class, access to an existing table.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2003, Frank Warmerdam
      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 "cpl_conv.h"
      31                 : #include "ogr_odbc.h"
      32                 : 
      33                 : CPL_CVSID("$Id: ogrodbctablelayer.cpp 24961 2012-09-23 18:06:49Z rouault $");
      34                 : /************************************************************************/
      35                 : /*                          OGRODBCTableLayer()                         */
      36                 : /************************************************************************/
      37                 : 
      38               0 : OGRODBCTableLayer::OGRODBCTableLayer( OGRODBCDataSource *poDSIn )
      39                 : 
      40                 : {
      41               0 :     poDS = poDSIn;
      42                 : 
      43               0 :     pszQuery = NULL;
      44                 : 
      45               0 :     bUpdateAccess = TRUE;
      46               0 :     bHaveSpatialExtents = FALSE;
      47                 : 
      48               0 :     iNextShapeId = 0;
      49                 : 
      50               0 :     nSRSId = -1;
      51                 : 
      52               0 :     poFeatureDefn = NULL;
      53                 :     
      54               0 :     pszTableName = NULL;
      55               0 :     pszSchemaName = NULL;
      56               0 : }
      57                 : 
      58                 : /************************************************************************/
      59                 : /*                          ~OGRODBCTableLayer()                          */
      60                 : /************************************************************************/
      61                 : 
      62               0 : OGRODBCTableLayer::~OGRODBCTableLayer()
      63                 : 
      64                 : {
      65               0 :     CPLFree( pszTableName );
      66               0 :     CPLFree( pszSchemaName );
      67                 : 
      68               0 :     CPLFree( pszQuery );
      69               0 :     ClearStatement();
      70               0 : }
      71                 : 
      72                 : /************************************************************************/
      73                 : /*                             Initialize()                             */
      74                 : /************************************************************************/
      75                 : 
      76               0 : CPLErr OGRODBCTableLayer::Initialize( const char *pszLayerName, 
      77                 :                                       const char *pszGeomCol )
      78                 : 
      79                 : {
      80               0 :     CPLODBCSession *poSession = poDS->GetSession();
      81                 : 
      82               0 :     CPLFree( pszFIDColumn );
      83               0 :     pszFIDColumn = NULL;
      84                 : 
      85                 : /* -------------------------------------------------------------------- */
      86                 : /*      Parse out schema name if present in layer.  We assume a         */
      87                 : /*      schema is provided if there is a dot in the name, and that      */
      88                 : /*      it is in the form <schema>.<tablename>                          */
      89                 : /* -------------------------------------------------------------------- */
      90               0 :     const char *pszDot = strstr(pszLayerName,".");
      91               0 :     if( pszDot != NULL )
      92                 :     {
      93               0 :         pszTableName = CPLStrdup(pszDot + 1);
      94               0 :         pszSchemaName = CPLStrdup(pszLayerName);
      95               0 :         pszSchemaName[pszDot - pszLayerName] = '\0';
      96                 :     }
      97                 :     else
      98                 :     {
      99               0 :         pszTableName = CPLStrdup(pszLayerName);
     100                 :     }
     101                 : 
     102                 : /* -------------------------------------------------------------------- */
     103                 : /*      Do we have a simple primary key?                                */
     104                 : /* -------------------------------------------------------------------- */
     105               0 :     CPLODBCStatement oGetKey( poSession );
     106                 :     
     107               0 :     if( oGetKey.GetPrimaryKeys( pszTableName, NULL, pszSchemaName ) 
     108                 :         && oGetKey.Fetch() )
     109                 :     {
     110               0 :         pszFIDColumn = CPLStrdup(oGetKey.GetColData( 3 ));
     111                 :         
     112               0 :         if( oGetKey.Fetch() ) // more than one field in key! 
     113                 :         {
     114               0 :             CPLFree( pszFIDColumn );
     115               0 :             pszFIDColumn = NULL;
     116                 : 
     117                 :             CPLDebug( "OGR_ODBC", "Table %s has multiple primary key fields, "
     118               0 :                       "ignoring them all.", pszTableName );
     119                 :         }
     120                 :     }
     121                 : 
     122                 : /* -------------------------------------------------------------------- */
     123                 : /*      Have we been provided a geometry column?                        */
     124                 : /* -------------------------------------------------------------------- */
     125               0 :     CPLFree( pszGeomColumn );
     126               0 :     if( pszGeomCol == NULL )
     127               0 :         pszGeomColumn = NULL;
     128                 :     else
     129               0 :         pszGeomColumn = CPLStrdup( pszGeomCol );
     130                 : 
     131                 : /* -------------------------------------------------------------------- */
     132                 : /*      Get the column definitions for this table.                      */
     133                 : /* -------------------------------------------------------------------- */
     134               0 :     CPLODBCStatement oGetCol( poSession );
     135                 :     CPLErr eErr;
     136                 : 
     137               0 :     if( !oGetCol.GetColumns( pszTableName, NULL, pszSchemaName ) )
     138               0 :         return CE_Failure;
     139                 : 
     140               0 :     eErr = BuildFeatureDefn( pszLayerName, &oGetCol );
     141               0 :     if( eErr != CE_None )
     142               0 :         return eErr;
     143                 : 
     144               0 :     if( poFeatureDefn->GetFieldCount() == 0 )
     145                 :     {
     146                 :         CPLError( CE_Warning, CPLE_AppDefined, 
     147                 :                   "No column definitions found for table '%s', layer not usable.", 
     148               0 :                   pszLayerName );
     149               0 :         return CE_Failure;
     150                 :     }
     151                 : 
     152                 : /* -------------------------------------------------------------------- */
     153                 : /*      Do we have XMIN, YMIN, XMAX, YMAX extent fields?                */
     154                 : /* -------------------------------------------------------------------- */
     155               0 :     if( poFeatureDefn->GetFieldIndex( "XMIN" ) != -1 
     156                 :         && poFeatureDefn->GetFieldIndex( "XMAX" ) != -1 
     157                 :         && poFeatureDefn->GetFieldIndex( "YMIN" ) != -1 
     158                 :         && poFeatureDefn->GetFieldIndex( "YMAX" ) != -1 )
     159                 :     {
     160               0 :         bHaveSpatialExtents = TRUE;
     161                 :         CPLDebug( "OGR_ODBC", "Table %s has geometry extent fields.",
     162               0 :                   pszLayerName );
     163                 :     }
     164                 :         
     165                 : /* -------------------------------------------------------------------- */
     166                 : /*      If we got a geometry column, does it exist?  Is it binary?      */
     167                 : /* -------------------------------------------------------------------- */
     168               0 :     if( pszGeomColumn != NULL )
     169                 :     {
     170               0 :         int iColumn = oGetCol.GetColId( pszGeomColumn );
     171               0 :         if( iColumn < 0 )
     172                 :         {
     173                 :             CPLError( CE_Failure, CPLE_AppDefined, 
     174                 :                       "Column %s requested for geometry, but it does not exist.", 
     175               0 :                       pszGeomColumn );
     176               0 :             CPLFree( pszGeomColumn );
     177               0 :             pszGeomColumn = NULL;
     178                 :         }
     179                 :         else
     180                 :         {
     181               0 :             if( CPLODBCStatement::GetTypeMapping(
     182                 :                     oGetCol.GetColType( iColumn )) == SQL_C_BINARY )
     183               0 :                 bGeomColumnWKB = TRUE;
     184                 :         }
     185                 :     }
     186                 : 
     187                 : 
     188               0 :     return CE_None;
     189                 : }
     190                 : 
     191                 : /************************************************************************/
     192                 : /*                           ClearStatement()                           */
     193                 : /************************************************************************/
     194                 : 
     195               0 : void OGRODBCTableLayer::ClearStatement()
     196                 : 
     197                 : {
     198               0 :     if( poStmt != NULL )
     199                 :     {
     200               0 :         delete poStmt;
     201               0 :         poStmt = NULL;
     202                 :     }
     203               0 : }
     204                 : 
     205                 : /************************************************************************/
     206                 : /*                            GetStatement()                            */
     207                 : /************************************************************************/
     208                 : 
     209               0 : CPLODBCStatement *OGRODBCTableLayer::GetStatement()
     210                 : 
     211                 : {
     212               0 :     if( poStmt == NULL )
     213               0 :         ResetStatement();
     214                 : 
     215               0 :     return poStmt;
     216                 : }
     217                 : 
     218                 : /************************************************************************/
     219                 : /*                           ResetStatement()                           */
     220                 : /************************************************************************/
     221                 : 
     222               0 : OGRErr OGRODBCTableLayer::ResetStatement()
     223                 : 
     224                 : {
     225               0 :     ClearStatement();
     226                 : 
     227               0 :     iNextShapeId = 0;
     228                 : 
     229               0 :     poStmt = new CPLODBCStatement( poDS->GetSession() );
     230               0 :     poStmt->Append( "SELECT * FROM " );
     231               0 :     poStmt->Append( poFeatureDefn->GetName() );
     232                 : 
     233                 :     /* Append attribute query if we have it */
     234               0 :     if( pszQuery != NULL )
     235               0 :         poStmt->Appendf( " WHERE %s", pszQuery );
     236                 : 
     237                 :     /* If we have a spatial filter, and per record extents, query on it */
     238               0 :     if( m_poFilterGeom != NULL && bHaveSpatialExtents )
     239                 :     {
     240               0 :         if( pszQuery == NULL )
     241               0 :             poStmt->Append( " WHERE" );
     242                 :         else
     243               0 :             poStmt->Append( " AND" );
     244                 :         
     245                 :         poStmt->Appendf( " XMAX > %.8f AND XMIN < %.8f"
     246                 :                          " AND YMAX > %.8f AND YMIN < %.8f", 
     247                 :                          m_sFilterEnvelope.MinX, m_sFilterEnvelope.MaxX, 
     248               0 :                          m_sFilterEnvelope.MinY, m_sFilterEnvelope.MaxY );
     249                 :     }
     250                 : 
     251               0 :     CPLDebug( "OGR_ODBC", "ExecuteSQL(%s)", poStmt->GetCommand() );
     252               0 :     if( poStmt->ExecuteSQL() )
     253               0 :         return OGRERR_NONE;
     254                 :     else
     255                 :     {
     256               0 :         delete poStmt;
     257               0 :         poStmt = NULL;
     258               0 :         return OGRERR_FAILURE;
     259                 :     }
     260                 : }
     261                 : 
     262                 : /************************************************************************/
     263                 : /*                            ResetReading()                            */
     264                 : /************************************************************************/
     265                 : 
     266               0 : void OGRODBCTableLayer::ResetReading()
     267                 : 
     268                 : {
     269               0 :     ClearStatement();
     270               0 :     OGRODBCLayer::ResetReading();
     271               0 : }
     272                 : 
     273                 : /************************************************************************/
     274                 : /*                             GetFeature()                             */
     275                 : /************************************************************************/
     276                 : 
     277               0 : OGRFeature *OGRODBCTableLayer::GetFeature( long nFeatureId )
     278                 : 
     279                 : {
     280               0 :     if( pszFIDColumn == NULL )
     281               0 :         return OGRODBCLayer::GetFeature( nFeatureId );
     282                 : 
     283               0 :     ClearStatement();
     284                 : 
     285               0 :     iNextShapeId = nFeatureId;
     286                 : 
     287               0 :     poStmt = new CPLODBCStatement( poDS->GetSession() );
     288               0 :     poStmt->Append( "SELECT * FROM " );
     289               0 :     poStmt->Append( poFeatureDefn->GetName() );
     290               0 :     poStmt->Appendf( " WHERE %s = %ld", pszFIDColumn, nFeatureId );
     291                 : 
     292               0 :     if( !poStmt->ExecuteSQL() )
     293                 :     {
     294               0 :         delete poStmt;
     295               0 :         poStmt = NULL;
     296               0 :         return NULL;
     297                 :     }
     298                 : 
     299               0 :     return GetNextRawFeature();
     300                 : }
     301                 : 
     302                 : /************************************************************************/
     303                 : /*                         SetAttributeFilter()                         */
     304                 : /************************************************************************/
     305                 : 
     306               0 : OGRErr OGRODBCTableLayer::SetAttributeFilter( const char *pszQuery )
     307                 : 
     308                 : {
     309               0 :     if( (pszQuery == NULL && this->pszQuery == NULL)
     310                 :         || (pszQuery != NULL && this->pszQuery != NULL 
     311                 :             && EQUAL(pszQuery,this->pszQuery)) )
     312               0 :         return OGRERR_NONE;
     313                 : 
     314               0 :     CPLFree( this->pszQuery );
     315               0 :     this->pszQuery = (pszQuery != NULL ) ? CPLStrdup( pszQuery ) : NULL;
     316                 : 
     317               0 :     ClearStatement();
     318                 : 
     319               0 :     return OGRERR_NONE;
     320                 : }
     321                 : 
     322                 : 
     323                 : /************************************************************************/
     324                 : /*                           TestCapability()                           */
     325                 : /************************************************************************/
     326                 : 
     327               0 : int OGRODBCTableLayer::TestCapability( const char * pszCap )
     328                 : 
     329                 : {
     330               0 :     if( EQUAL(pszCap,OLCRandomRead) )
     331               0 :         return TRUE;
     332                 :         
     333                 :     else 
     334               0 :         return OGRODBCLayer::TestCapability( pszCap );
     335                 : }
     336                 : 
     337                 : /************************************************************************/
     338                 : /*                          GetFeatureCount()                           */
     339                 : /*                                                                      */
     340                 : /*      If a spatial filter is in effect, we turn control over to       */
     341                 : /*      the generic counter.  Otherwise we return the total count.      */
     342                 : /*      Eventually we should consider implementing a more efficient     */
     343                 : /*      way of counting features matching a spatial query.              */
     344                 : /************************************************************************/
     345                 : 
     346               0 : int OGRODBCTableLayer::GetFeatureCount( int bForce )
     347                 : 
     348                 : {
     349               0 :     if( m_poFilterGeom != NULL )
     350               0 :         return OGRODBCLayer::GetFeatureCount( bForce );
     351                 : 
     352               0 :     CPLODBCStatement oStmt( poDS->GetSession() );
     353               0 :     oStmt.Append( "SELECT COUNT(*) FROM " );
     354               0 :     oStmt.Append( poFeatureDefn->GetName() );
     355                 : 
     356               0 :     if( pszQuery != NULL )
     357               0 :         oStmt.Appendf( " WHERE %s", pszQuery );
     358                 : 
     359               0 :     if( !oStmt.ExecuteSQL() || !oStmt.Fetch() )
     360                 :     {
     361                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     362                 :                   "GetFeatureCount() failed on query %s.\n%s",
     363               0 :                   oStmt.GetCommand(), poDS->GetSession()->GetLastError() );
     364               0 :         return OGRODBCLayer::GetFeatureCount(bForce);
     365                 :     }
     366                 : 
     367               0 :     return atoi(oStmt.GetColData(0));
     368                 : }
     369                 : 
     370                 : /************************************************************************/
     371                 : /*                           GetSpatialRef()                            */
     372                 : /*                                                                      */
     373                 : /*      We override this to try and fetch the table SRID from the       */
     374                 : /*      geometry_columns table if the srsid is -2 (meaning we           */
     375                 : /*      haven't yet even looked for it).                                */
     376                 : /************************************************************************/
     377                 : 
     378               0 : OGRSpatialReference *OGRODBCTableLayer::GetSpatialRef()
     379                 : 
     380                 : {
     381                 : #ifdef notdef
     382                 :     if( nSRSId == -2 )
     383                 :     {
     384                 :         PGconn          *hPGConn = poDS->GetPGConn();
     385                 :         PGresult        *hResult;
     386                 :         char            szCommand[1024];
     387                 : 
     388                 :         nSRSId = -1;
     389                 : 
     390                 :         poDS->SoftStartTransaction();
     391                 : 
     392                 :         sprintf( szCommand, 
     393                 :                  "SELECT srid FROM geometry_columns "
     394                 :                  "WHERE f_table_name = '%s'",
     395                 :                  poFeatureDefn->GetName() );
     396                 :         hResult = PQexec(hPGConn, szCommand );
     397                 : 
     398                 :         if( hResult 
     399                 :             && PQresultStatus(hResult) == PGRES_TUPLES_OK 
     400                 :             && PQntuples(hResult) == 1 )
     401                 :         {
     402                 :             nSRSId = atoi(PQgetvalue(hResult,0,0));
     403                 :         }
     404                 : 
     405                 :         poDS->SoftCommit();
     406                 :     }
     407                 : #endif
     408                 : 
     409               0 :     return OGRODBCLayer::GetSpatialRef();
     410                 : }
     411                 : 

Generated by: LCOV version 1.7