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: 2025-05-31 00:00:17 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             :     VFKReaderSQLite *poReader =
      98          27 :         cpl::down_cast<VFKReaderSQLite *>(m_poDataBlock->GetReader());
      99          27 :     sqlite3 *poDB = poReader->m_poDB;
     100             : 
     101          27 :     int rc = sqlite3_prepare_v2(poDB, pszSQLCommand, -1, &m_hStmt, nullptr);
     102          27 :     if (rc != SQLITE_OK)
     103             :     {
     104           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     105             :                  "In ExecuteSQL(): sqlite3_prepare_v2(%s):\n  %s",
     106             :                  pszSQLCommand, sqlite3_errmsg(poDB));
     107             : 
     108           0 :         if (m_hStmt != nullptr)
     109             :         {
     110           0 :             FinalizeSQL();
     111             :         }
     112           0 :         return OGRERR_FAILURE;
     113             :     }
     114          27 :     rc = sqlite3_step(m_hStmt);
     115          27 :     if (rc != SQLITE_ROW)
     116             :     {
     117           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     118             :                  "In ExecuteSQL(): sqlite3_step(%s):\n  %s", pszSQLCommand,
     119             :                  sqlite3_errmsg(poDB));
     120             : 
     121           0 :         if (m_hStmt)
     122             :         {
     123           0 :             FinalizeSQL();
     124             :         }
     125             : 
     126           0 :         return OGRERR_FAILURE;
     127             :     }
     128             : 
     129          27 :     return OGRERR_NONE;
     130             : }
     131             : 
     132             : /*!
     133             :   \brief VFKFeatureSQLite constructor (derived from VFKFeature)
     134             : 
     135             :   Read VFK feature from VFK file and insert it into DB
     136             : */
     137           0 : VFKFeatureSQLite::VFKFeatureSQLite(const VFKFeature *poVFKFeature)
     138           0 :     : IVFKFeature(poVFKFeature->m_poDataBlock),
     139             :       // Starts at 1.
     140             :       m_iRowId(
     141           0 :           static_cast<int>(poVFKFeature->m_poDataBlock->GetFeatureCount() + 1)),
     142           0 :       m_hStmt(nullptr)
     143             : {
     144           0 :     m_nFID = poVFKFeature->m_nFID;
     145           0 : }
     146             : 
     147             : /*!
     148             :   \brief Load geometry (point layers)
     149             : 
     150             :   \todo Implement (really needed?)
     151             : 
     152             :   \return true on success or false on failure
     153             : */
     154           0 : bool VFKFeatureSQLite::LoadGeometryPoint()
     155             : {
     156           0 :     return false;
     157             : }
     158             : 
     159             : /*!
     160             :   \brief Load geometry (linestring SBP layer)
     161             : 
     162             :   \todo Implement (really needed?)
     163             : 
     164             :   \return true on success or false on failure
     165             : */
     166           0 : bool VFKFeatureSQLite::LoadGeometryLineStringSBP()
     167             : {
     168           0 :     return false;
     169             : }
     170             : 
     171             : /*!
     172             :   \brief Load geometry (linestring HP/DPM layer)
     173             : 
     174             :   \todo Implement (really needed?)
     175             : 
     176             :   \return true on success or false on failure
     177             : */
     178           0 : bool VFKFeatureSQLite::LoadGeometryLineStringHP()
     179             : {
     180           0 :     return false;
     181             : }
     182             : 
     183             : /*!
     184             :   \brief Load geometry (polygon BUD/PAR layers)
     185             : 
     186             :   \todo Implement (really needed?)
     187             : 
     188             :   \return true on success or false on failure
     189             : */
     190           0 : bool VFKFeatureSQLite::LoadGeometryPolygon()
     191             : {
     192           0 :     return false;
     193             : }
     194             : 
     195             : /*!
     196             :   \brief Load feature properties from DB
     197             : 
     198             :   \param poFeature pointer to OGR feature
     199             : 
     200             :   \return OGRERR_NONE on success or OGRERR_FAILURE on failure
     201             : */
     202          31 : OGRErr VFKFeatureSQLite::LoadProperties(OGRFeature *poFeature)
     203             : {
     204             :     sqlite3_stmt *hStmt =
     205          31 :         cpl::down_cast<VFKDataBlockSQLite *>(m_poDataBlock)->m_hStmt;
     206          31 :     if (hStmt == nullptr)
     207             :     {
     208             :         /* random access */
     209          27 :         CPLString osSQL;
     210             : 
     211             :         osSQL.Printf("SELECT * FROM %s WHERE rowid = %d",
     212          27 :                      m_poDataBlock->GetName(), m_iRowId);
     213          27 :         if (ExecuteSQL(osSQL.c_str()) != OGRERR_NONE)
     214           0 :             return OGRERR_FAILURE;
     215             : 
     216          27 :         hStmt = m_hStmt;
     217             :     }
     218             :     else
     219             :     {
     220             :         /* sequential access */
     221             :         VFKReaderSQLite *poReader =
     222           4 :             cpl::down_cast<VFKReaderSQLite *>(m_poDataBlock->GetReader());
     223           4 :         if (poReader->ExecuteSQL(hStmt) != OGRERR_NONE)
     224             :         {
     225           0 :             cpl::down_cast<VFKDataBlockSQLite *>(m_poDataBlock)->m_hStmt =
     226             :                 nullptr;
     227           0 :             return OGRERR_FAILURE;
     228             :         }
     229             :     }
     230             : 
     231          31 :     int nPropertyCount = m_poDataBlock->GetPropertyCount();
     232         469 :     for (int iField = 0; iField < nPropertyCount; iField++)
     233             :     {
     234         438 :         if (sqlite3_column_type(hStmt, iField) ==
     235             :             SQLITE_NULL) /* skip null values */
     236         127 :             continue;
     237             :         OGRFieldType fType =
     238         311 :             poFeature->GetDefnRef()->GetFieldDefn(iField)->GetType();
     239         311 :         switch (fType)
     240             :         {
     241         116 :             case OFTInteger:
     242         116 :                 poFeature->SetField(iField, sqlite3_column_int(hStmt, iField));
     243         116 :                 break;
     244         129 :             case OFTInteger64:
     245         129 :                 poFeature->SetField(iField,
     246             :                                     sqlite3_column_int64(hStmt, iField));
     247         129 :                 break;
     248          26 :             case OFTReal:
     249          26 :                 poFeature->SetField(iField,
     250             :                                     sqlite3_column_double(hStmt, iField));
     251          26 :                 break;
     252          40 :             default:
     253          80 :                 poFeature->SetField(
     254          40 :                     iField, (const char *)sqlite3_column_text(hStmt, iField));
     255          40 :                 break;
     256             :         }
     257             :     }
     258             : 
     259          31 :     if (m_poDataBlock->GetReader()->HasFileField())
     260             :     {
     261             :         /* open option FILE_FIELD=YES specified, append extra
     262             :          * attribute */
     263           1 :         poFeature->SetField(
     264             :             nPropertyCount,
     265           1 :             CPLGetFilename(m_poDataBlock->GetReader()->GetFilename()));
     266             :     }
     267             : 
     268          31 :     FinalizeSQL();
     269             : 
     270          31 :     return OGRERR_NONE;
     271             : }

Generated by: LCOV version 1.14