Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: GDAL 4 : * Purpose: gdal "vector info" subcommand 5 : * Author: Even Rouault <even dot rouault at spatialys.com> 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 2024, Even Rouault <even dot rouault at spatialys.com> 9 : * 10 : * SPDX-License-Identifier: MIT 11 : ****************************************************************************/ 12 : 13 : #include "gdalalg_vector_info.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 : /* GDALVectorInfoAlgorithm::GDALVectorInfoAlgorithm() */ 27 : /************************************************************************/ 28 : 29 99 : GDALVectorInfoAlgorithm::GDALVectorInfoAlgorithm(bool standaloneStep) 30 : : GDALVectorPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL, 31 0 : ConstructorOptions() 32 99 : .SetStandaloneStep(standaloneStep) 33 99 : .SetInputDatasetMaxCount(1) 34 198 : .SetAddDefaultArguments(false)) 35 : { 36 99 : AddOutputFormatArg(&m_format).SetChoices("json", "text"); 37 99 : AddOpenOptionsArg(&m_openOptions).SetHiddenForCLI(!standaloneStep); 38 99 : AddInputFormatsArg(&m_inputFormats) 39 297 : .AddMetadataItem(GAAMDI_REQUIRED_CAPABILITIES, {GDAL_DCAP_VECTOR}) 40 99 : .SetHiddenForCLI(!standaloneStep); 41 : auto &datasetArg = 42 : AddInputDatasetArg(&m_inputDataset, GDAL_OF_VECTOR, 43 99 : /* positionalAndRequired = */ standaloneStep) 44 198 : .AddAlias("dataset") 45 99 : .SetHiddenForCLI(!standaloneStep); 46 : auto &layerArg = 47 99 : AddLayerNameArg(&m_layerNames).SetMutualExclusionGroup("layer-sql"); 48 99 : SetAutoCompleteFunctionForLayerName(layerArg, datasetArg); 49 : AddArg("features", 0, 50 : _("List all features (beware of RAM consumption on large layers)"), 51 198 : &m_listFeatures) 52 99 : .SetMutualExclusionGroup("summary-features"); 53 : AddArg("summary", 0, _("List the layer names and the geometry type"), 54 198 : &m_summaryOnly) 55 99 : .SetMutualExclusionGroup("summary-features"); 56 : AddArg("sql", 0, 57 : _("Execute the indicated SQL statement and return the result"), 58 198 : &m_sql) 59 99 : .SetReadFromFileAtSyntaxAllowed() 60 198 : .SetMetaVar("<statement>|@<filename>") 61 99 : .SetRemoveSQLCommentsEnabled() 62 99 : .SetMutualExclusionGroup("layer-sql"); 63 : AddArg("where", 0, 64 : _("Attribute query in a restricted form of the queries used in the " 65 : "SQL WHERE statement"), 66 198 : &m_where) 67 99 : .SetReadFromFileAtSyntaxAllowed() 68 198 : .SetMetaVar("<WHERE>|@<filename>") 69 99 : .SetRemoveSQLCommentsEnabled(); 70 99 : AddArg("dialect", 0, _("SQL dialect"), &m_dialect); 71 : AddArg(GDAL_ARG_NAME_UPDATE, 0, _("Open the dataset in update mode"), 72 198 : &m_update) 73 99 : .SetHiddenForCLI(!standaloneStep) 74 : .AddAction( 75 4 : [this]() 76 : { 77 2 : if (m_update) 78 : { 79 2 : ReportError(CE_Warning, CPLE_AppDefined, 80 : "Option 'update' is deprecated since GDAL 3.12 " 81 : "and will be removed in GDAL 3.13. Use 'gdal " 82 : "vector sql --update' instead."); 83 : } 84 99 : }); 85 99 : AddOutputStringArg(&m_output); 86 : AddArg("stdout", 0, 87 : _("Directly output on stdout (format=text mode only). If enabled, " 88 : "output-string will be empty"), 89 198 : &m_stdout) 90 99 : .SetHiddenForCLI(); 91 99 : } 92 : 93 : /************************************************************************/ 94 : /* GDALVectorInfoAlgorithm::RunStep() */ 95 : /************************************************************************/ 96 : 97 27 : bool GDALVectorInfoAlgorithm::RunStep(GDALPipelineStepRunContext &) 98 : { 99 27 : CPLAssert(m_inputDataset.size() == 1); 100 27 : auto poSrcDS = m_inputDataset[0].GetDatasetRef(); 101 27 : CPLAssert(poSrcDS); 102 : 103 27 : if (m_format.empty()) 104 17 : m_format = IsCalledFromCommandLine() ? "text" : "json"; 105 : 106 54 : CPLStringList aosOptions; 107 : 108 27 : aosOptions.AddString("--cli"); 109 : 110 27 : if (m_format == "json") 111 : { 112 15 : aosOptions.AddString("-json"); 113 : } 114 : 115 27 : if (m_summaryOnly) 116 : { 117 4 : aosOptions.AddString("-summary"); 118 : } 119 23 : else if (m_listFeatures) 120 : { 121 2 : aosOptions.AddString("-features"); 122 : } 123 : 124 27 : if (!m_sql.empty()) 125 : { 126 3 : aosOptions.AddString("-sql"); 127 3 : aosOptions.AddString(m_sql.c_str()); 128 : } 129 27 : if (!m_where.empty()) 130 : { 131 2 : aosOptions.AddString("-where"); 132 2 : aosOptions.AddString(m_where.c_str()); 133 : } 134 27 : if (!m_dialect.empty()) 135 : { 136 2 : aosOptions.AddString("-dialect"); 137 2 : aosOptions.AddString(m_dialect.c_str()); 138 : } 139 27 : if (m_stdout) 140 : { 141 4 : aosOptions.AddString("-stdout"); 142 : } 143 : 144 : // Must be last, as positional 145 27 : aosOptions.AddString("dummy"); 146 29 : for (const std::string &name : m_layerNames) 147 2 : aosOptions.AddString(name.c_str()); 148 : 149 27 : if (m_layerNames.empty()) 150 : { 151 25 : aosOptions.AddString("-al"); 152 : } 153 : 154 : GDALVectorInfoOptions *psInfo = 155 27 : GDALVectorInfoOptionsNew(aosOptions.List(), nullptr); 156 : 157 27 : char *ret = GDALVectorInfo(GDALDataset::ToHandle(poSrcDS), psInfo); 158 27 : GDALVectorInfoOptionsFree(psInfo); 159 27 : if (!ret) 160 1 : return false; 161 : 162 26 : m_output = ret; 163 26 : CPLFree(ret); 164 : 165 26 : return true; 166 : } 167 : 168 : GDALVectorInfoAlgorithmStandalone::~GDALVectorInfoAlgorithmStandalone() = 169 : default; 170 : 171 : //! @endcond