LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/mysql - ogrmysqlresultlayer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 110 88 80.0 %
Date: 2012-12-26 Functions: 10 6 60.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrmysqlresultlayer.cpp 20460 2010-08-27 20:06:26Z rouault $
       3                 :  *
       4                 :  * Project:  OpenGIS Simple Features Reference Implementation
       5                 :  * Purpose:  Implements OGRMySQLResultLayer 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 "cpl_conv.h"
      32                 : #include "ogr_mysql.h"
      33                 : 
      34                 : CPL_CVSID("$Id: ogrmysqlresultlayer.cpp 20460 2010-08-27 20:06:26Z rouault $");
      35                 : 
      36                 : /************************************************************************/
      37                 : /*                        OGRMySQLResultLayer()                         */
      38                 : /************************************************************************/
      39                 : 
      40               4 : OGRMySQLResultLayer::OGRMySQLResultLayer( OGRMySQLDataSource *poDSIn, 
      41                 :                                           const char * pszRawQueryIn,
      42               4 :                                           MYSQL_RES *hResultSetIn )
      43                 : {
      44               4 :     poDS = poDSIn;
      45                 : 
      46               4 :     iNextShapeId = 0;
      47                 : 
      48               4 :     pszRawStatement = CPLStrdup(pszRawQueryIn);
      49                 : 
      50               4 :     hResultSet = hResultSetIn;
      51                 : 
      52               4 :     BuildFullQueryStatement();
      53                 : 
      54               4 :     poFeatureDefn = ReadResultDefinition();
      55               4 : }
      56                 : 
      57                 : /************************************************************************/
      58                 : /*                        ~OGRMySQLResultLayer()                        */
      59                 : /************************************************************************/
      60                 : 
      61               4 : OGRMySQLResultLayer::~OGRMySQLResultLayer()
      62                 : 
      63                 : {
      64               4 :     CPLFree( pszRawStatement );
      65               4 : }
      66                 : 
      67                 : /************************************************************************/
      68                 : /*                        ReadResultDefinition()                        */
      69                 : /*                                                                      */
      70                 : /*      Build a schema from the current resultset.                      */
      71                 : /************************************************************************/
      72                 : 
      73               4 : OGRFeatureDefn *OGRMySQLResultLayer::ReadResultDefinition()
      74                 : 
      75                 : {
      76                 : 
      77                 : /* -------------------------------------------------------------------- */
      78                 : /*      Parse the returned table information.                           */
      79                 : /* -------------------------------------------------------------------- */
      80               4 :     OGRFeatureDefn *poDefn = new OGRFeatureDefn( "sql_statement" );
      81                 :     int            iRawField;
      82                 : 
      83               4 :     poDefn->Reference();
      84                 :     int width;
      85                 :     int precision;
      86                 : 
      87               4 :     mysql_field_seek( hResultSet, 0 );
      88               4 :     for( iRawField = 0; 
      89                 :          iRawField < (int) mysql_num_fields(hResultSet); 
      90                 :          iRawField++ )
      91                 :     {
      92              13 :         MYSQL_FIELD *psMSField = mysql_fetch_field( hResultSet );
      93              13 :         OGRFieldDefn    oField( psMSField->name, OFTString);
      94                 : 
      95              13 :         switch( psMSField->type )
      96                 :         {
      97                 :           case FIELD_TYPE_TINY:
      98                 :           case FIELD_TYPE_SHORT:
      99                 :           case FIELD_TYPE_LONG:
     100                 :           case FIELD_TYPE_INT24:
     101                 :           case FIELD_TYPE_LONGLONG:
     102               4 :             oField.SetType( OFTInteger );
     103               4 :             width = (int)psMSField->length;
     104               4 :             oField.SetWidth(width);
     105               4 :             poDefn->AddFieldDefn( &oField );
     106               4 :             break;
     107                 : 
     108                 :           case FIELD_TYPE_DECIMAL:
     109                 : #ifdef FIELD_TYPE_NEWDECIMAL
     110                 :           case FIELD_TYPE_NEWDECIMAL:
     111                 : #endif
     112               4 :             oField.SetType( OFTReal );
     113                 :             
     114                 :             // a bunch of hackery to munge the widths that MySQL gives 
     115                 :             // us into corresponding widths and precisions for OGR
     116               4 :             precision =    (int)psMSField->decimals;
     117               4 :             width = (int)psMSField->length;
     118               4 :             if (!precision)
     119               2 :                 width = width - 1;
     120               4 :             width = width - precision;
     121                 :             
     122               4 :             oField.SetWidth(width);
     123               4 :             oField.SetPrecision(precision);
     124               4 :             poDefn->AddFieldDefn( &oField );
     125               4 :             break;
     126                 : 
     127                 :           case FIELD_TYPE_FLOAT:
     128                 :           case FIELD_TYPE_DOUBLE:
     129                 :          /* MYSQL_FIELD is always reporting ->length = 22 and ->decimals = 31
     130                 :             for double type regardless of the data it returned. In an example,
     131                 :             the data it returned had only 5 or 6 decimal places which were
     132                 :             exactly as entered into the database but reported the decimals
     133                 :             as 31. */
     134                 :          /* Assuming that a length of 22 means no particular width and 31
     135                 :             decimals means no particular precision. */
     136               1 :             width = (int)psMSField->length;
     137               1 :             precision = (int)psMSField->decimals;
     138               1 :             oField.SetType( OFTReal );
     139               1 :             if( width != 22 )
     140               0 :                 oField.SetWidth(width);
     141               1 :             if( precision != 31 )
     142               0 :                 oField.SetPrecision(precision);
     143               1 :             poDefn->AddFieldDefn( &oField );
     144               1 :             break;
     145                 : 
     146                 :           case FIELD_TYPE_DATE:
     147               0 :             oField.SetType( OFTDate );
     148               0 :             oField.SetWidth(0);
     149               0 :             poDefn->AddFieldDefn( &oField );
     150               0 :             break;
     151                 : 
     152                 :           case FIELD_TYPE_TIME:
     153               0 :             oField.SetType( OFTTime );
     154               0 :             oField.SetWidth(0);
     155               0 :             poDefn->AddFieldDefn( &oField );
     156               0 :             break;
     157                 : 
     158                 :           case FIELD_TYPE_TIMESTAMP:
     159                 :           case FIELD_TYPE_DATETIME:
     160               0 :             oField.SetType( OFTDateTime );
     161               0 :             oField.SetWidth(0);
     162               0 :             poDefn->AddFieldDefn( &oField );
     163               0 :             break;
     164                 : 
     165                 :           case FIELD_TYPE_YEAR:
     166                 :           case FIELD_TYPE_STRING:
     167                 :           case FIELD_TYPE_VAR_STRING:
     168               1 :             oField.SetType( OFTString );
     169               1 :             oField.SetWidth((int)psMSField->length);
     170               1 :             poDefn->AddFieldDefn( &oField );
     171               1 :             break;
     172                 : 
     173                 :           case FIELD_TYPE_TINY_BLOB:
     174                 :           case FIELD_TYPE_MEDIUM_BLOB:
     175                 :           case FIELD_TYPE_LONG_BLOB:
     176                 :           case FIELD_TYPE_BLOB:
     177               1 :             if( psMSField->charsetnr == 63 )
     178               0 :                 oField.SetType( OFTBinary );
     179                 :             else
     180               1 :                 oField.SetType( OFTString );
     181               1 :             oField.SetWidth((int)psMSField->max_length);
     182               1 :             poDefn->AddFieldDefn( &oField );
     183               1 :             break;
     184                 :                         
     185                 :           case FIELD_TYPE_GEOMETRY:
     186               2 :             if (pszGeomColumn == NULL)
     187                 :             {
     188               2 :                 pszGeomColumnTable = CPLStrdup( psMSField->table);
     189               2 :                 pszGeomColumn = CPLStrdup( psMSField->name);
     190                 :             }
     191                 :             break;
     192                 :             
     193                 :           default:
     194                 :             // any other field we ignore. 
     195                 :             break;
     196                 :         }
     197                 :         
     198                 :         // assume a FID name first, and if it isn't there
     199                 :         // take a field that is not null, a primary key, 
     200                 :         // and is an integer-like field
     201              13 :         if( EQUAL(psMSField->name,"ogc_fid") )
     202                 :         {
     203               0 :             bHasFid = TRUE;
     204               0 :             pszFIDColumn = CPLStrdup(oField.GetNameRef());
     205               0 :             continue;
     206                 :         } else  
     207              13 :         if (IS_NOT_NULL(psMSField->flags)
     208                 :             && IS_PRI_KEY(psMSField->flags)
     209                 :             && 
     210                 :                 (
     211                 :                     psMSField->type == FIELD_TYPE_TINY
     212                 :                     || psMSField->type == FIELD_TYPE_SHORT
     213                 :                     || psMSField->type == FIELD_TYPE_LONG
     214                 :                     || psMSField->type == FIELD_TYPE_INT24
     215                 :                     || psMSField->type == FIELD_TYPE_LONGLONG
     216                 :                 )
     217                 :             )
     218                 :         {
     219               1 :            bHasFid = TRUE;
     220               1 :            pszFIDColumn = CPLStrdup(oField.GetNameRef());
     221               1 :            continue;
     222                 :         }
     223                 :     }
     224                 : 
     225                 : 
     226               4 :     poDefn->SetGeomType( wkbNone );
     227                 : 
     228               4 :     if (pszGeomColumn) 
     229                 :     {
     230               2 :         char*        pszType=NULL;
     231               2 :         CPLString    osCommand;
     232                 :         char           **papszRow;  
     233                 :          
     234                 :         // set to unknown first
     235               2 :         poDefn->SetGeomType( wkbUnknown );
     236                 :         
     237                 :         osCommand.Printf(
     238                 :                 "SELECT type FROM geometry_columns WHERE f_table_name='%s'",
     239               2 :                 pszGeomColumnTable );
     240                 : 
     241               2 :         if( hResultSet != NULL )
     242               2 :             mysql_free_result( hResultSet );
     243               2 :         hResultSet = NULL;
     244                 : 
     245               2 :         if( !mysql_query( poDS->GetConn(), osCommand ) )
     246               2 :             hResultSet = mysql_store_result( poDS->GetConn() );
     247                 : 
     248               2 :         papszRow = NULL;
     249               2 :         if( hResultSet != NULL )
     250               2 :             papszRow = mysql_fetch_row( hResultSet );
     251                 : 
     252                 : 
     253               2 :         if( papszRow != NULL && papszRow[0] != NULL )
     254                 :         {
     255               1 :             pszType = papszRow[0];
     256                 : 
     257               1 :             OGRwkbGeometryType nGeomType = OGRFromOGCGeomType(pszType);
     258                 : 
     259               1 :             poDefn->SetGeomType( nGeomType );
     260                 : 
     261                 :         } 
     262                 : 
     263               2 :     nSRSId = FetchSRSId();
     264                 :     } 
     265                 : 
     266                 : 
     267               4 :     return poDefn;
     268                 : }
     269                 : 
     270                 : /************************************************************************/
     271                 : /*                      BuildFullQueryStatement()                       */
     272                 : /************************************************************************/
     273                 : 
     274               4 : void OGRMySQLResultLayer::BuildFullQueryStatement()
     275                 : 
     276                 : {
     277               4 :     if( pszQueryStatement != NULL )
     278                 :     {
     279               0 :         CPLFree( pszQueryStatement );
     280               0 :         pszQueryStatement = NULL;
     281                 :     }
     282                 : 
     283               4 :     pszQueryStatement = CPLStrdup(pszRawStatement);
     284               4 : }
     285                 : 
     286                 : /************************************************************************/
     287                 : /*                            ResetReading()                            */
     288                 : /************************************************************************/
     289                 : 
     290              19 : void OGRMySQLResultLayer::ResetReading()
     291                 : 
     292                 : {
     293              19 :     OGRMySQLLayer::ResetReading();
     294              19 : }
     295                 : 
     296                 : /************************************************************************/
     297                 : /*                          GetFeatureCount()                           */
     298                 : /************************************************************************/
     299                 : 
     300               2 : int OGRMySQLResultLayer::GetFeatureCount( int bForce )
     301                 : 
     302                 : {
     303                 :     // I wonder if we could do anything smart here...
     304                 :     // ... not till MySQL grows up (HB)
     305               2 :     return OGRMySQLLayer::GetFeatureCount( bForce );
     306                 : }
     307                 : 
     308                 : /************************************************************************/
     309                 : /*                           TestCapability()                           */
     310                 : /************************************************************************/
     311                 : 
     312               0 : int OGRMySQLResultLayer::TestCapability( const char * pszCap )
     313                 : 
     314                 : {
     315               0 :     return FALSE;
     316                 : }
     317                 : 

Generated by: LCOV version 1.7