LCOV - code coverage report
Current view: top level - apps - gdalalg_vector_export_schema.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 54 66 81.8 %
Date: 2026-07-09 08:35:43 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL
       4             :  * Purpose:  gdal "vector export-schema" subcommand
       5             :  * Author:   Alessandro Pasotti <elpaso at itopen dot it>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2026, Alessandro Pasotti <elpaso at itopen dot it>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "gdalalg_vector_export_schema.h"
      14             : 
      15             : #include "cpl_conv.h"
      16             : #include "gdal_priv.h"
      17             : #include "gdal_utils.h"
      18             : 
      19             : //! @cond Doxygen_Suppress
      20             : 
      21             : #ifndef _
      22             : #define _(x) (x)
      23             : #endif
      24             : 
      25             : /************************************************************************/
      26             : /*  GDALVectorExportSchemaAlgorithm::GDALVectorExportSchemaAlgorithm()  */
      27             : /************************************************************************/
      28             : 
      29          88 : GDALVectorExportSchemaAlgorithm::GDALVectorExportSchemaAlgorithm(
      30          88 :     bool standaloneStep)
      31             :     : GDALVectorPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL,
      32           0 :                                       ConstructorOptions()
      33          88 :                                           .SetStandaloneStep(standaloneStep)
      34          88 :                                           .SetInputDatasetMaxCount(1)
      35         176 :                                           .SetAddDefaultArguments(false))
      36             : {
      37          88 :     if (standaloneStep)
      38          49 :         AddProgressArg(/* hidden = */ true);
      39             : 
      40          88 :     AddOpenOptionsArg(&m_openOptions).SetHiddenForCLI(!standaloneStep);
      41          88 :     AddInputFormatsArg(&m_inputFormats)
      42         264 :         .AddMetadataItem(GAAMDI_REQUIRED_CAPABILITIES, {GDAL_DCAP_VECTOR})
      43          88 :         .SetHiddenForCLI(!standaloneStep);
      44             : 
      45             :     auto &datasetArg =
      46          88 :         AddInputDatasetArg(&m_inputDataset, GDAL_OF_VECTOR).AddAlias("dataset");
      47          88 :     if (!standaloneStep)
      48          39 :         datasetArg.SetHidden();
      49          88 :     auto &layerArg = AddLayerNameArg(&m_layerNames).AddAlias("layer");
      50          88 :     SetAutoCompleteFunctionForLayerName(layerArg, datasetArg);
      51          88 :     AddOutputStringArg(&m_output);
      52          88 :     AddStdoutArg(&m_stdout);
      53             :     AddArg(GDAL_ARG_NAME_OUTPUT, 'o',
      54             :            _("Output file name. If not specified, output is sent to stdout"),
      55          88 :            &m_outputFileName);
      56             :     AddOverwriteArg(&m_overwrite,
      57          88 :                     _("Whether overwriting existing output file is allowed"));
      58          88 : }
      59             : 
      60             : /************************************************************************/
      61             : /*              GDALVectorExportSchemaAlgorithm::RunStep()              */
      62             : /************************************************************************/
      63             : 
      64           7 : bool GDALVectorExportSchemaAlgorithm::RunStep(GDALPipelineStepRunContext &)
      65             : {
      66           7 :     CPLAssert(m_inputDataset.size() == 1);
      67           7 :     auto poSrcDS = m_inputDataset[0].GetDatasetRef();
      68           7 :     CPLAssert(poSrcDS);
      69             : 
      70          14 :     CPLStringList aosOptions;
      71             : 
      72           7 :     aosOptions.AddString("-schema");
      73           7 :     aosOptions.AddString("--cli");
      74             : 
      75             :     // Must be last, as positional
      76           7 :     aosOptions.AddString("dummy");
      77             : 
      78           7 :     for (const std::string &name : m_layerNames)
      79           0 :         aosOptions.AddString(name.c_str());
      80             : 
      81           7 :     if (m_layerNames.empty())
      82             :     {
      83           7 :         aosOptions.AddString("-al");
      84             :     }
      85             : 
      86             :     GDALVectorInfoOptions *psInfo =
      87           7 :         GDALVectorInfoOptionsNew(aosOptions.List(), nullptr);
      88             : 
      89           7 :     char *ret = GDALVectorInfo(GDALDataset::ToHandle(poSrcDS), psInfo);
      90           7 :     GDALVectorInfoOptionsFree(psInfo);
      91           7 :     if (!ret)
      92           0 :         return false;
      93             : 
      94           7 :     const auto outFileNameArg = GetArg(GDAL_ARG_NAME_OUTPUT);
      95           7 :     if (outFileNameArg && outFileNameArg->IsExplicitlySet())
      96             :     {
      97             :         // Check if file exists
      98             :         VSIStatBufL sStat;
      99           4 :         if (VSIStatL(m_outputFileName.c_str(), &sStat) == 0)
     100             :         {
     101           2 :             const auto overwriteArg = GetArg(GDAL_ARG_NAME_OVERWRITE);
     102           2 :             if (overwriteArg && overwriteArg->GetType() == GAAT_BOOLEAN)
     103             :             {
     104           2 :                 if (!overwriteArg->GDALAlgorithmArg::Get<bool>())
     105             :                 {
     106           1 :                     CPLError(CE_Failure, CPLE_AppDefined,
     107             :                              "File '%s' already exists. Specify the "
     108             :                              "--overwrite option to overwrite it.",
     109             :                              m_outputFileName.c_str());
     110           1 :                     CPLFree(ret);
     111           1 :                     return false;
     112             :                 }
     113             :                 else
     114             :                 {
     115           1 :                     if (VSIUnlink(m_outputFileName.c_str()) != 0)
     116             :                     {
     117           0 :                         CPLError(CE_Failure, CPLE_AppDefined,
     118             :                                  "Failed to delete existing file '%s'",
     119             :                                  m_outputFileName.c_str());
     120           0 :                         CPLFree(ret);
     121           0 :                         return false;
     122             :                     }
     123             :                 }
     124             :             }
     125             :         }
     126             : 
     127           3 :         VSILFILE *fp = VSIFOpenL(m_outputFileName.c_str(), "wb");
     128           3 :         if (!fp)
     129             :         {
     130           0 :             CPLError(CE_Failure, CPLE_FileIO, "Failed to open output file '%s'",
     131             :                      m_outputFileName.c_str());
     132           0 :             CPLFree(ret);
     133           0 :             return false;
     134             :         }
     135           3 :         auto nBytesWritten = VSIFWriteL(ret, 1, strlen(ret), fp);
     136           3 :         VSIFCloseL(fp);
     137           3 :         if (nBytesWritten != strlen(ret))
     138             :         {
     139           0 :             CPLError(CE_Failure, CPLE_AppDefined,
     140             :                      "Failed to write output file '%s'",
     141             :                      m_outputFileName.c_str());
     142           0 :             CPLFree(ret);
     143           0 :             return false;
     144             :         }
     145             :     }
     146             :     else
     147             :     {
     148           3 :         m_output = ret;
     149             :     }
     150           6 :     CPLFree(ret);
     151             : 
     152           6 :     return true;
     153             : }
     154             : 
     155             : GDALVectorExportSchemaAlgorithmStandalone::
     156             :     ~GDALVectorExportSchemaAlgorithmStandalone() = default;
     157             : 
     158             : //! @endcond

Generated by: LCOV version 1.14