LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/mysql - ogrmysqllayer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 125 106 84.8 %
Date: 2010-01-09 Functions: 12 8 66.7 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrmysqllayer.cpp 14272 2008-04-12 13:47:54Z rouault $
       3                 :  *
       4                 :  * Project:  OpenGIS Simple Features Reference Implementation
       5                 :  * Purpose:  Implements OGRMySQLLayer class.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  * Author:   Howard Butler, hobu@hobu.net
       8                 :  *
       9                 :  ******************************************************************************
      10                 :  * Copyright (c) 2004, 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 "ogr_mysql.h"
      32                 : #include "cpl_conv.h"
      33                 : #include "cpl_string.h"
      34                 : 
      35                 : CPL_CVSID("$Id: ogrmysqllayer.cpp 14272 2008-04-12 13:47:54Z rouault $");
      36                 : 
      37                 : /************************************************************************/
      38                 : /*                           OGRMySQLLayer()                            */
      39                 : /************************************************************************/
      40                 : 
      41               7 : OGRMySQLLayer::OGRMySQLLayer()
      42                 : 
      43                 : {
      44               7 :     poDS = NULL;
      45                 : 
      46               7 :     pszGeomColumn = NULL;
      47               7 :     pszGeomColumnTable = NULL;
      48               7 :     pszFIDColumn = NULL;
      49               7 :     pszQueryStatement = NULL;
      50                 : 
      51               7 :     bHasFid = FALSE;
      52               7 :     pszFIDColumn = NULL;
      53                 : 
      54               7 :     iNextShapeId = 0;
      55               7 :     nResultOffset = 0;
      56                 : 
      57               7 :     poSRS = NULL;
      58               7 :     nSRSId = -2; // we haven't even queried the database for it yet. 
      59                 : 
      60               7 :     poFeatureDefn = NULL;
      61                 : 
      62               7 :     hResultSet = NULL;
      63               7 : }
      64                 : 
      65                 : /************************************************************************/
      66                 : /*                           ~OGRMySQLLayer()                           */
      67                 : /************************************************************************/
      68                 : 
      69               7 : OGRMySQLLayer::~OGRMySQLLayer()
      70                 : 
      71                 : {
      72               7 :     if( m_nFeaturesRead > 0 && poFeatureDefn != NULL )
      73                 :     {
      74                 :         CPLDebug( "MySQL", "%d features read on layer '%s'.",
      75                 :                   (int) m_nFeaturesRead, 
      76               6 :                   poFeatureDefn->GetName() );
      77                 :     }
      78                 : 
      79               7 :     ResetReading();
      80                 : 
      81               7 :     CPLFree( pszGeomColumn );
      82               7 :     CPLFree( pszGeomColumnTable );
      83               7 :     CPLFree( pszFIDColumn );
      84               7 :     CPLFree( pszQueryStatement );
      85                 : 
      86               7 :     if( poSRS != NULL )
      87               1 :         poSRS->Release();
      88                 : 
      89               7 :     if( poFeatureDefn )
      90               7 :         poFeatureDefn->Release();
      91               7 : }
      92                 : 
      93                 : /************************************************************************/
      94                 : /*                            ResetReading()                            */
      95                 : /************************************************************************/
      96                 : 
      97              82 : void OGRMySQLLayer::ResetReading()
      98                 : 
      99                 : {
     100              82 :     iNextShapeId = 0;
     101                 : 
     102              82 :     if( hResultSet != NULL )
     103                 :     {
     104              25 :         mysql_free_result( hResultSet );
     105              25 :         hResultSet = NULL;
     106                 : 
     107              25 :         poDS->InterruptLongResult();
     108                 :     }
     109              82 : }
     110                 : 
     111                 : /************************************************************************/
     112                 : /*                           GetNextFeature()                           */
     113                 : /************************************************************************/
     114                 : 
     115              66 : OGRFeature *OGRMySQLLayer::GetNextFeature()
     116                 : 
     117                 : {
     118                 : 
     119               2 :     for( ; TRUE; )
     120                 :     {
     121                 :         OGRFeature      *poFeature;
     122                 : 
     123              66 :         poFeature = GetNextRawFeature();
     124              66 :         if( poFeature == NULL )
     125              11 :             return NULL;
     126                 : 
     127              55 :         if( (m_poFilterGeom == NULL
     128                 :             || FilterGeometry( poFeature->GetGeometryRef() ) )
     129                 :             && (m_poAttrQuery == NULL
     130                 :                 || m_poAttrQuery->Evaluate( poFeature )) )
     131              53 :             return poFeature;
     132                 : 
     133               2 :         delete poFeature;
     134                 :     }
     135                 : }
     136                 : /************************************************************************/
     137                 : /*                          RecordToFeature()                           */
     138                 : /*                                                                      */
     139                 : /*      Convert the indicated record of the current result set into     */
     140                 : /*      a feature.                                                      */
     141                 : /************************************************************************/
     142                 : 
     143              56 : OGRFeature *OGRMySQLLayer::RecordToFeature( char **papszRow,
     144                 :                                             unsigned long *panLengths )
     145                 : 
     146                 : {
     147              56 :     mysql_field_seek( hResultSet, 0 );
     148                 : 
     149                 : /* -------------------------------------------------------------------- */
     150                 : /*      Create a feature from the current result.                       */
     151                 : /* -------------------------------------------------------------------- */
     152                 :     int         iField;
     153              56 :     OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
     154                 : 
     155              56 :     poFeature->SetFID( iNextShapeId );
     156              56 :     m_nFeaturesRead++;
     157                 : 
     158                 : /* ==================================================================== */
     159                 : /*      Transfer all result fields we can.                              */
     160                 : /* ==================================================================== */
     161             272 :     for( iField = 0; 
     162                 :          iField < (int) mysql_num_fields(hResultSet);
     163                 :          iField++ )
     164                 :     {
     165                 :         int     iOGRField;
     166             216 :         MYSQL_FIELD *psMSField = mysql_fetch_field(hResultSet);
     167                 : 
     168                 : /* -------------------------------------------------------------------- */
     169                 : /*      Handle FID.                                                     */
     170                 : /* -------------------------------------------------------------------- */
     171             216 :         if( bHasFid && EQUAL(psMSField->name,pszFIDColumn) )
     172                 :         {
     173              33 :             if( papszRow[iField] == NULL )
     174                 :             {
     175                 :                 CPLError( CE_Failure, CPLE_AppDefined,
     176               0 :                           "NULL primary key in RecordToFeature()" );
     177               0 :                 return NULL;
     178                 :             }
     179                 : 
     180              33 :             poFeature->SetFID( atoi(papszRow[iField]) );
     181                 :         }
     182                 : 
     183             216 :         if( papszRow[iField] == NULL ) 
     184                 :         {
     185                 : //            CPLDebug("MYSQL", "%s was null for %d", psMSField->name,
     186                 : //                     iNextShapeId);
     187              57 :             continue;
     188                 :         }
     189                 : 
     190                 : /* -------------------------------------------------------------------- */
     191                 : /*      Handle MySQL geometry                                           */
     192                 : /* -------------------------------------------------------------------- */
     193             159 :         if( pszGeomColumn && EQUAL(psMSField->name,pszGeomColumn))
     194                 :         {
     195              33 :             OGRGeometry *poGeometry = NULL;
     196                 :             
     197                 :             // Geometry columns will have the first 4 bytes contain the SRID.
     198                 :             OGRGeometryFactory::createFromWkb(
     199              33 :                 ((GByte *)papszRow[iField]) + 4, 
     200                 :                 NULL,
     201                 :                 &poGeometry,
     202              66 :                 panLengths[iField] - 4 );
     203                 : 
     204              33 :             if( poGeometry != NULL )
     205                 :             {
     206              32 :                 poGeometry->assignSpatialReference( poSRS );
     207              32 :                 poFeature->SetGeometryDirectly( poGeometry );
     208                 :             }
     209              33 :             continue;
     210                 :         }
     211                 : 
     212                 : 
     213                 : /* -------------------------------------------------------------------- */
     214                 : /*      Transfer regular data fields.                                   */
     215                 : /* -------------------------------------------------------------------- */
     216             126 :         iOGRField = poFeatureDefn->GetFieldIndex(psMSField->name);
     217             126 :         if( iOGRField < 0 )
     218              29 :             continue;
     219                 : 
     220              97 :         OGRFieldDefn *psFieldDefn = poFeatureDefn->GetFieldDefn( iOGRField );
     221                 : 
     222              97 :         if( psFieldDefn->GetType() == OFTBinary )
     223                 :         {
     224               0 :             poFeature->SetField( iOGRField, panLengths[iField], 
     225               0 :                                  (GByte *) papszRow[iField] );
     226                 :         }
     227                 :         else
     228                 :         {
     229              97 :             poFeature->SetField( iOGRField, papszRow[iField] );
     230                 :         }
     231                 :     }
     232                 : 
     233              56 :     return poFeature;
     234                 : }
     235                 : 
     236                 : /************************************************************************/
     237                 : /*                         GetNextRawFeature()                          */
     238                 : /************************************************************************/
     239                 : 
     240              66 : OGRFeature *OGRMySQLLayer::GetNextRawFeature()
     241                 : 
     242                 : {
     243                 : /* -------------------------------------------------------------------- */
     244                 : /*      Do we need to establish an initial query?                       */
     245                 : /* -------------------------------------------------------------------- */
     246              66 :     if( iNextShapeId == 0 && hResultSet == NULL )
     247                 :     {
     248                 :         CPLAssert( pszQueryStatement != NULL );
     249                 : 
     250              23 :         poDS->RequestLongResult( this );
     251                 : 
     252              23 :         if( mysql_query( poDS->GetConn(), pszQueryStatement ) )
     253                 :         {
     254               0 :             poDS->ReportError( pszQueryStatement );
     255               0 :             return NULL;
     256                 :         }
     257                 : 
     258              23 :         hResultSet = mysql_use_result( poDS->GetConn() );
     259              23 :         if( hResultSet == NULL )
     260                 :         {
     261               0 :             poDS->ReportError( "mysql_use_result() failed on query." );
     262               0 :             return FALSE;
     263                 :         }
     264                 :     }
     265                 : 
     266                 : /* -------------------------------------------------------------------- */
     267                 : /*      Fetch next record.                                              */
     268                 : /* -------------------------------------------------------------------- */
     269                 :     char **papszRow;
     270                 :     unsigned long *panLengths;
     271                 : 
     272              66 :     papszRow = mysql_fetch_row( hResultSet );
     273              66 :     if( papszRow == NULL )
     274                 :     {
     275              11 :         ResetReading();
     276              11 :         return NULL;
     277                 :     }
     278                 : 
     279              55 :     panLengths = mysql_fetch_lengths( hResultSet );
     280                 : 
     281                 : /* -------------------------------------------------------------------- */
     282                 : /*      Process record.                                                 */
     283                 : /* -------------------------------------------------------------------- */
     284              55 :     OGRFeature *poFeature = RecordToFeature( papszRow, panLengths );
     285                 : 
     286              55 :     iNextShapeId++;
     287                 : 
     288              55 :     return poFeature;
     289                 : }
     290                 : 
     291                 : /************************************************************************/
     292                 : /*                             GetFeature()                             */
     293                 : /*                                                                      */
     294                 : /*      Note that we actually override this in OGRMySQLTableLayer.      */
     295                 : /************************************************************************/
     296                 : 
     297               0 : OGRFeature *OGRMySQLLayer::GetFeature( long nFeatureId )
     298                 : 
     299                 : {
     300               0 :     return OGRLayer::GetFeature( nFeatureId );
     301                 : }
     302                 : 
     303                 : /************************************************************************/
     304                 : /*                            GetFIDColumn()                            */
     305                 : /************************************************************************/
     306                 : 
     307               0 : const char *OGRMySQLLayer::GetFIDColumn() 
     308                 : 
     309                 : {
     310               0 :     if( pszFIDColumn != NULL )
     311               0 :         return pszFIDColumn;
     312                 :     else
     313               0 :         return "";
     314                 : }
     315                 : 
     316                 : /************************************************************************/
     317                 : /*                         GetGeometryColumn()                          */
     318                 : /************************************************************************/
     319                 : 
     320               0 : const char *OGRMySQLLayer::GetGeometryColumn() 
     321                 : 
     322                 : {
     323               0 :     if( pszGeomColumn != NULL )
     324               0 :         return pszGeomColumn;
     325                 :     else
     326               0 :         return "";
     327                 : }
     328                 : 
     329                 : 
     330                 : /************************************************************************/
     331                 : /*                         FetchSRSId()                                 */
     332                 : /************************************************************************/
     333                 : 
     334               5 : int OGRMySQLLayer::FetchSRSId()
     335                 : {
     336                 :   char         szCommand[1024];
     337                 :     char           **papszRow;  
     338                 :     
     339               5 :     if( hResultSet != NULL )
     340               1 :         mysql_free_result( hResultSet );
     341               5 :     hResultSet = NULL;
     342                 :         
     343                 :     sprintf( szCommand, 
     344                 :              "SELECT srid FROM geometry_columns "
     345                 :              "WHERE f_table_name = '%s'",
     346               5 :              pszGeomColumnTable );
     347                 : 
     348               5 :     if( !mysql_query( poDS->GetConn(), szCommand ) )
     349               5 :         hResultSet = mysql_store_result( poDS->GetConn() );
     350                 : 
     351               5 :     papszRow = NULL;
     352               5 :     if( hResultSet != NULL )
     353               5 :         papszRow = mysql_fetch_row( hResultSet );
     354                 :         
     355                 : 
     356               5 :     if( papszRow != NULL && papszRow[0] != NULL )
     357                 :     {
     358               2 :         nSRSId = atoi(papszRow[0]);
     359                 :     }
     360                 : 
     361                 :     // make sure to free our results
     362               5 :     if( hResultSet != NULL )
     363               5 :         mysql_free_result( hResultSet );
     364               5 :     hResultSet = NULL;
     365                 :         
     366               5 :   return nSRSId;
     367                 : }
     368                 : 
     369                 : /************************************************************************/
     370                 : /*                           GetSpatialRef()                            */
     371                 : /************************************************************************/
     372                 : 
     373               1 : OGRSpatialReference *OGRMySQLLayer::GetSpatialRef()
     374                 : 
     375                 : {
     376                 : 
     377                 : 
     378               1 :     if( poSRS == NULL && nSRSId > -1 )
     379                 :     {
     380               1 :         poSRS = poDS->FetchSRS( nSRSId );
     381               1 :         if( poSRS != NULL )
     382               1 :             poSRS->Reference();
     383                 :         else
     384               0 :             nSRSId = -1;
     385                 :     }
     386                 : 
     387               1 :     return poSRS;
     388                 : 
     389                 : }

Generated by: LCOV version 1.7