LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/vfk - vfkfeaturesqlite.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 53 91 58.2 %
Date: 2024-11-21 22:18:42 Functions: 5 12 41.7 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  VFK Reader - Feature definition (SQLite)
       4             :  * Purpose:  Implements VFKFeatureSQLite class.
       5             :  * Author:   Martin Landa, landa.martin gmail.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2012-2018, Martin Landa <landa.martin gmail.com>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "vfkreader.h"
      14             : #include "vfkreaderp.h"
      15             : 
      16             : #include "cpl_conv.h"
      17             : #include "cpl_error.h"
      18             : 
      19             : /*!
      20             :   \brief VFKFeatureSQLite constructor (from DB)
      21             : 
      22             :   Read VFK feature from DB
      23             : 
      24             :   \param poDataBlock pointer to related IVFKDataBlock
      25             : */
      26           0 : VFKFeatureSQLite::VFKFeatureSQLite(IVFKDataBlock *poDataBlock)
      27             :     : IVFKFeature(poDataBlock),
      28             :       // Starts at 1.
      29           0 :       m_iRowId(static_cast<int>(poDataBlock->GetFeatureCount() + 1)),
      30           0 :       m_hStmt(nullptr)
      31             : {
      32             :     // Set FID from DB.
      33           0 :     SetFIDFromDB();  // -> m_nFID
      34           0 : }
      35             : 
      36             : /*!
      37             :   \brief VFKFeatureSQLite constructor
      38             : 
      39             :   \param poDataBlock pointer to related IVFKDataBlock
      40             :   \param iRowId feature DB rowid (starts at 1)
      41             :   \param nFID feature id
      42             : */
      43         688 : VFKFeatureSQLite::VFKFeatureSQLite(IVFKDataBlock *poDataBlock, int iRowId,
      44         688 :                                    GIntBig nFID)
      45         688 :     : IVFKFeature(poDataBlock), m_iRowId(iRowId), m_hStmt(nullptr)
      46             : {
      47         688 :     m_nFID = nFID;
      48         688 : }
      49             : 
      50             : /*!
      51             :   \brief Read FID from DB
      52             : */
      53           0 : OGRErr VFKFeatureSQLite::SetFIDFromDB()
      54             : {
      55           0 :     CPLString osSQL;
      56             : 
      57             :     osSQL.Printf("SELECT %s FROM %s WHERE rowid = %d", FID_COLUMN,
      58           0 :                  m_poDataBlock->GetName(), m_iRowId);
      59           0 :     if (ExecuteSQL(osSQL.c_str()) != OGRERR_NONE)
      60           0 :         return OGRERR_FAILURE;
      61             : 
      62           0 :     m_nFID = sqlite3_column_int(m_hStmt, 0);
      63             : 
      64           0 :     FinalizeSQL();
      65             : 
      66           0 :     return OGRERR_NONE;
      67             : }
      68             : 
      69             : /*!
      70             :   \brief Set DB row id
      71             : 
      72             :   \param iRowId row id to be set
      73             : */
      74         196 : void VFKFeatureSQLite::SetRowId(int iRowId)
      75             : {
      76         196 :     m_iRowId = iRowId;
      77         196 : }
      78             : 
      79             : /*!
      80             :   \brief Finalize SQL statement
      81             : */
      82          31 : void VFKFeatureSQLite::FinalizeSQL()
      83             : {
      84          31 :     sqlite3_finalize(m_hStmt);
      85          31 :     m_hStmt = nullptr;
      86          31 : }
      87             : 
      88             : /*!
      89             :   \brief Execute SQL (select) statement
      90             : 
      91             :   \param pszSQLCommand SQL command string
      92             : 
      93             :   \return OGRERR_NONE on success or OGRERR_FAILURE on error
      94             : */
      95          27 : OGRErr VFKFeatureSQLite::ExecuteSQL(const char *pszSQLCommand)
      96             : {
      97          27 :     VFKReaderSQLite *poReader = (VFKReaderSQLite *)m_poDataBlock->GetReader();
      98          27 :     sqlite3 *poDB = poReader->m_poDB;
      99             : 
     100          27 :     int rc = sqlite3_prepare_v2(poDB, pszSQLCommand, -1, &m_hStmt, nullptr);
     101          27 :     if (rc != SQLITE_OK)
     102             :     {
     103           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     104             :                  "In ExecuteSQL(): sqlite3_prepare_v2(%s):\n  %s",
     105             :                  pszSQLCommand, sqlite3_errmsg(poDB));
     106             : 
     107           0 :         if (m_hStmt != nullptr)
     108             :         {
     109           0 :             FinalizeSQL();
     110             :         }
     111           0 :         return OGRERR_FAILURE;
     112             :     }
     113          27 :     rc = sqlite3_step(m_hStmt);
     114          27 :     if (rc != SQLITE_ROW)
     115             :     {
     116           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     117             :                  "In ExecuteSQL(): sqlite3_step(%s):\n  %s", pszSQLCommand,
     118             :                  sqlite3_errmsg(poDB));
     119             : 
     120           0 :         if (m_hStmt)
     121             :         {
     122           0 :             FinalizeSQL();
     123             :         }
     124             : 
     125           0 :         return OGRERR_FAILURE;
     126             :     }
     127             : 
     128          27 :     return OGRERR_NONE;
     129             : }
     130             : 
     131             : /*!
     132             :   \brief VFKFeatureSQLite constructor (derived from VFKFeature)
     133             : 
     134             :   Read VFK feature from VFK file and insert it into DB
     135             : */
     136           0 : VFKFeatureSQLite::VFKFeatureSQLite(const VFKFeature *poVFKFeature)
     137           0 :     : IVFKFeature(poVFKFeature->m_poDataBlock),
     138             :       // Starts at 1.
     139             :       m_iRowId(
     140           0 :           static_cast<int>(poVFKFeature->m_poDataBlock->GetFeatureCount() + 1)),
     141           0 :       m_hStmt(nullptr)
     142             : {
     143           0 :     m_nFID = poVFKFeature->m_nFID;
     144           0 : }
     145             : 
     146             : /*!
     147             :   \brief Load geometry (point layers)
     148             : 
     149             :   \todo Implement (really needed?)
     150             : 
     151             :   \return true on success or false on failure
     152             : */
     153           0 : bool VFKFeatureSQLite::LoadGeometryPoint()
     154             : {
     155           0 :     return false;
     156             : }
     157             : 
     158             : /*!
     159             :   \brief Load geometry (linestring SBP layer)
     160             : 
     161             :   \todo Implement (really needed?)
     162             : 
     163             :   \return true on success or false on failure
     164             : */
     165           0 : bool VFKFeatureSQLite::LoadGeometryLineStringSBP()
     166             : {
     167           0 :     return false;
     168             : }
     169             : 
     170             : /*!
     171             :   \brief Load geometry (linestring HP/DPM layer)
     172             : 
     173             :   \todo Implement (really needed?)
     174             : 
     175             :   \return true on success or false on failure
     176             : */
     177           0 : bool VFKFeatureSQLite::LoadGeometryLineStringHP()
     178             : {
     179           0 :     return false;
     180             : }
     181             : 
     182             : /*!
     183             :   \brief Load geometry (polygon BUD/PAR layers)
     184             : 
     185             :   \todo Implement (really needed?)
     186             : 
     187             :   \return true on success or false on failure
     188             : */
     189           0 : bool VFKFeatureSQLite::LoadGeometryPolygon()
     190             : {
     191           0 :     return false;
     192             : }
     193             : 
     194             : /*!
     195             :   \brief Load feature properties from DB
     196             : 
     197             :   \param poFeature pointer to OGR feature
     198             : 
     199             :   \return OGRERR_NONE on success or OGRERR_FAILURE on failure
     200             : */
     201          31 : OGRErr VFKFeatureSQLite::LoadProperties(OGRFeature *poFeature)
     202             : {
     203          31 :     sqlite3_stmt *hStmt = ((VFKDataBlockSQLite *)m_poDataBlock)->m_hStmt;
     204          31 :     if (hStmt == nullptr)
     205             :     {
     206             :         /* random access */
     207          27 :         CPLString osSQL;
     208             : 
     209             :         osSQL.Printf("SELECT * FROM %s WHERE rowid = %d",
     210          27 :                      m_poDataBlock->GetName(), m_iRowId);
     211          27 :         if (ExecuteSQL(osSQL.c_str()) != OGRERR_NONE)
     212           0 :             return OGRERR_FAILURE;
     213             : 
     214          27 :         hStmt = m_hStmt;
     215             :     }
     216             :     else
     217             :     {
     218             :         /* sequential access */
     219             :         VFKReaderSQLite *poReader =
     220           4 :             (VFKReaderSQLite *)m_poDataBlock->GetReader();
     221           4 :         if (poReader->ExecuteSQL(hStmt) != OGRERR_NONE)
     222             :         {
     223           0 :             ((VFKDataBlockSQLite *)m_poDataBlock)->m_hStmt = nullptr;
     224           0 :             return OGRERR_FAILURE;
     225             :         }
     226             :     }
     227             : 
     228          31 :     int nPropertyCount = m_poDataBlock->GetPropertyCount();
     229         469 :     for (int iField = 0; iField < nPropertyCount; iField++)
     230             :     {
     231         438 :         if (sqlite3_column_type(hStmt, iField) ==
     232             :             SQLITE_NULL) /* skip null values */
     233         127 :             continue;
     234             :         OGRFieldType fType =
     235         311 :             poFeature->GetDefnRef()->GetFieldDefn(iField)->GetType();
     236         311 :         switch (fType)
     237             :         {
     238         116 :             case OFTInteger:
     239         116 :                 poFeature->SetField(iField, sqlite3_column_int(hStmt, iField));
     240         116 :                 break;
     241         129 :             case OFTInteger64:
     242         129 :                 poFeature->SetField(iField,
     243             :                                     sqlite3_column_int64(hStmt, iField));
     244         129 :                 break;
     245          26 :             case OFTReal:
     246          26 :                 poFeature->SetField(iField,
     247             :                                     sqlite3_column_double(hStmt, iField));
     248          26 :                 break;
     249          40 :             default:
     250          80 :                 poFeature->SetField(
     251          40 :                     iField, (const char *)sqlite3_column_text(hStmt, iField));
     252          40 :                 break;
     253             :         }
     254             :     }
     255             : 
     256          31 :     if (m_poDataBlock->GetReader()->HasFileField())
     257             :     {
     258             :         /* open option FILE_FIELD=YES specified, append extra
     259             :          * attribute */
     260           1 :         poFeature->SetField(
     261             :             nPropertyCount,
     262           1 :             CPLGetFilename(m_poDataBlock->GetReader()->GetFilename()));
     263             :     }
     264             : 
     265          31 :     FinalizeSQL();
     266             : 
     267          31 :     return OGRERR_NONE;
     268             : }

Generated by: LCOV version 1.14