LCOV - code coverage report
Current view: top level - apps - gdalalg_vector_export_schema.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 52 64 81.2 %
Date: 2026-06-03 12:46:18 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          87 : GDALVectorExportSchemaAlgorithm::GDALVectorExportSchemaAlgorithm(
      30          87 :     bool standaloneStep)
      31             :     : GDALVectorPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL,
      32           0 :                                       ConstructorOptions()
      33          87 :                                           .SetStandaloneStep(standaloneStep)
      34          87 :                                           .SetInputDatasetMaxCount(1)
      35         174 :                                           .SetAddDefaultArguments(false))
      36             : {
      37          87 :     AddOpenOptionsArg(&m_openOptions).SetHiddenForCLI(!standaloneStep);
      38          87 :     AddInputFormatsArg(&m_inputFormats)
      39         261 :         .AddMetadataItem(GAAMDI_REQUIRED_CAPABILITIES, {GDAL_DCAP_VECTOR})
      40          87 :         .SetHiddenForCLI(!standaloneStep);
      41             : 
      42             :     auto &datasetArg =
      43          87 :         AddInputDatasetArg(&m_inputDataset, GDAL_OF_VECTOR).AddAlias("dataset");
      44          87 :     if (!standaloneStep)
      45          39 :         datasetArg.SetHidden();
      46          87 :     auto &layerArg = AddLayerNameArg(&m_layerNames).AddAlias("layer");
      47          87 :     SetAutoCompleteFunctionForLayerName(layerArg, datasetArg);
      48          87 :     AddOutputStringArg(&m_output);
      49          87 :     AddStdoutArg(&m_stdout);
      50             :     AddArg(GDAL_ARG_NAME_OUTPUT, 'o',
      51             :            _("Output file name. If not specified, output is sent to stdout"),
      52          87 :            &m_outputFileName);
      53             :     AddOverwriteArg(&m_overwrite,
      54          87 :                     _("Whether overwriting existing output file is allowed"));
      55          87 : }
      56             : 
      57             : /************************************************************************/
      58             : /*              GDALVectorExportSchemaAlgorithm::RunStep()              */
      59             : /************************************************************************/
      60             : 
      61           7 : bool GDALVectorExportSchemaAlgorithm::RunStep(GDALPipelineStepRunContext &)
      62             : {
      63           7 :     CPLAssert(m_inputDataset.size() == 1);
      64           7 :     auto poSrcDS = m_inputDataset[0].GetDatasetRef();
      65           7 :     CPLAssert(poSrcDS);
      66             : 
      67          14 :     CPLStringList aosOptions;
      68             : 
      69           7 :     aosOptions.AddString("-schema");
      70           7 :     aosOptions.AddString("--cli");
      71             : 
      72             :     // Must be last, as positional
      73           7 :     aosOptions.AddString("dummy");
      74             : 
      75           7 :     for (const std::string &name : m_layerNames)
      76           0 :         aosOptions.AddString(name.c_str());
      77             : 
      78           7 :     if (m_layerNames.empty())
      79             :     {
      80           7 :         aosOptions.AddString("-al");
      81             :     }
      82             : 
      83             :     GDALVectorInfoOptions *psInfo =
      84           7 :         GDALVectorInfoOptionsNew(aosOptions.List(), nullptr);
      85             : 
      86           7 :     char *ret = GDALVectorInfo(GDALDataset::ToHandle(poSrcDS), psInfo);
      87           7 :     GDALVectorInfoOptionsFree(psInfo);
      88           7 :     if (!ret)
      89           0 :         return false;
      90             : 
      91           7 :     const auto outFileNameArg = GetArg(GDAL_ARG_NAME_OUTPUT);
      92           7 :     if (outFileNameArg && outFileNameArg->IsExplicitlySet())
      93             :     {
      94             :         // Check if file exists
      95             :         VSIStatBufL sStat;
      96           4 :         if (VSIStatL(m_outputFileName.c_str(), &sStat) == 0)
      97             :         {
      98           2 :             const auto overwriteArg = GetArg(GDAL_ARG_NAME_OVERWRITE);
      99           2 :             if (overwriteArg && overwriteArg->GetType() == GAAT_BOOLEAN)
     100             :             {
     101           2 :                 if (!overwriteArg->GDALAlgorithmArg::Get<bool>())
     102             :                 {
     103           1 :                     CPLError(CE_Failure, CPLE_AppDefined,
     104             :                              "File '%s' already exists. Specify the "
     105             :                              "--overwrite option to overwrite it.",
     106             :                              m_outputFileName.c_str());
     107           1 :                     CPLFree(ret);
     108           1 :                     return false;
     109             :                 }
     110             :                 else
     111             :                 {
     112           1 :                     if (VSIUnlink(m_outputFileName.c_str()) != 0)
     113             :                     {
     114           0 :                         CPLError(CE_Failure, CPLE_AppDefined,
     115             :                                  "Failed to delete existing file '%s'",
     116             :                                  m_outputFileName.c_str());
     117           0 :                         CPLFree(ret);
     118           0 :                         return false;
     119             :                     }
     120             :                 }
     121             :             }
     122             :         }
     123             : 
     124           3 :         VSILFILE *fp = VSIFOpenL(m_outputFileName.c_str(), "wb");
     125           3 :         if (!fp)
     126             :         {
     127           0 :             CPLError(CE_Failure, CPLE_FileIO, "Failed to open output file '%s'",
     128             :                      m_outputFileName.c_str());
     129           0 :             CPLFree(ret);
     130           0 :             return false;
     131             :         }
     132           3 :         auto nBytesWritten = VSIFWriteL(ret, 1, strlen(ret), fp);
     133           3 :         VSIFCloseL(fp);
     134           3 :         if (nBytesWritten != strlen(ret))
     135             :         {
     136           0 :             CPLError(CE_Failure, CPLE_AppDefined,
     137             :                      "Failed to write output file '%s'",
     138             :                      m_outputFileName.c_str());
     139           0 :             CPLFree(ret);
     140           0 :             return false;
     141             :         }
     142             :     }
     143             :     else
     144             :     {
     145           3 :         m_output = ret;
     146             :     }
     147           6 :     CPLFree(ret);
     148             : 
     149           6 :     return true;
     150             : }
     151             : 
     152             : GDALVectorExportSchemaAlgorithmStandalone::
     153             :     ~GDALVectorExportSchemaAlgorithmStandalone() = default;
     154             : 
     155             : //! @endcond

Generated by: LCOV version 1.14