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 130 : GDALVectorInfoAlgorithm::GDALVectorInfoAlgorithm(bool standaloneStep) 30 : : GDALVectorPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL, 31 0 : ConstructorOptions() 32 130 : .SetStandaloneStep(standaloneStep) 33 130 : .SetInputDatasetMaxCount(1) 34 260 : .SetAddDefaultArguments(false)) 35 : { 36 130 : AddOutputFormatArg(&m_format).SetChoices("json", "text"); 37 130 : AddOpenOptionsArg(&m_openOptions).SetHiddenForCLI(!standaloneStep); 38 130 : AddInputFormatsArg(&m_inputFormats) 39 390 : .AddMetadataItem(GAAMDI_REQUIRED_CAPABILITIES, {GDAL_DCAP_VECTOR}) 40 130 : .SetHiddenForCLI(!standaloneStep); 41 : auto &datasetArg = 42 : AddInputDatasetArg(&m_inputDataset, GDAL_OF_VECTOR, 43 130 : /* positionalAndRequired = */ standaloneStep) 44 260 : .AddAlias("dataset") 45 130 : .SetHiddenForCLI(!standaloneStep); 46 130 : auto &layerArg = AddLayerNameArg(&m_layerNames) 47 260 : .SetMutualExclusionGroup("layer-sql") 48 130 : .AddAlias("layer"); 49 130 : SetAutoCompleteFunctionForLayerName(layerArg, datasetArg); 50 : auto &argFeature = 51 : AddArg( 52 : "features", 0, 53 : _("List all features (beware of RAM consumption on large layers)"), 54 260 : &m_listFeatures) 55 130 : .SetMutualExclusionGroup("summary-features"); 56 : AddArg("summary", 0, _("List the layer names and the geometry type"), 57 260 : &m_summaryOnly) 58 130 : .SetMutualExclusionGroup("summary-features"); 59 : AddArg("limit", 0, 60 : _("Limit the number of features per layer (implies --features)"), 61 260 : &m_limit) 62 130 : .SetMinValueIncluded(0) 63 260 : .SetMetaVar("FEATURE-COUNT") 64 132 : .AddAction([&argFeature]() { argFeature.Set(true); }); 65 : AddArg("sql", 0, 66 : _("Execute the indicated SQL statement and return the result"), 67 260 : &m_sql) 68 130 : .SetReadFromFileAtSyntaxAllowed() 69 260 : .SetMetaVar("<statement>|@<filename>") 70 130 : .SetRemoveSQLCommentsEnabled() 71 130 : .SetMutualExclusionGroup("layer-sql"); 72 : AddArg("where", 0, 73 : _("Attribute query in a restricted form of the queries used in the " 74 : "SQL WHERE statement"), 75 260 : &m_where) 76 130 : .SetReadFromFileAtSyntaxAllowed() 77 260 : .SetMetaVar("<WHERE>|@<filename>") 78 130 : .SetRemoveSQLCommentsEnabled(); 79 130 : AddArg("dialect", 0, _("SQL dialect"), &m_dialect); 80 : AddArg(GDAL_ARG_NAME_UPDATE, 0, _("Open the dataset in update mode"), 81 260 : &m_update) 82 130 : .SetHiddenForCLI(!standaloneStep) 83 : .AddAction( 84 4 : [this]() 85 : { 86 2 : if (m_update) 87 : { 88 2 : ReportError(CE_Warning, CPLE_AppDefined, 89 : "Option 'update' is deprecated since GDAL 3.12 " 90 : "and will be removed in GDAL 3.13. Use 'gdal " 91 : "vector sql --update' instead."); 92 : } 93 130 : }); 94 130 : AddOutputStringArg(&m_output); 95 130 : AddStdoutArg(&m_stdout); 96 : 97 130 : AddValidationAction( 98 71 : [this]() 99 : { 100 64 : if (!m_sql.empty() && !m_where.empty()) 101 : { 102 1 : ReportError(CE_Failure, CPLE_NotSupported, 103 : "Option 'sql' and 'where' are mutually exclusive"); 104 1 : return false; 105 : } 106 63 : return true; 107 : }); 108 130 : } 109 : 110 : /************************************************************************/ 111 : /* GDALVectorInfoAlgorithm::RunStep() */ 112 : /************************************************************************/ 113 : 114 28 : bool GDALVectorInfoAlgorithm::RunStep(GDALPipelineStepRunContext &) 115 : { 116 28 : CPLAssert(m_inputDataset.size() == 1); 117 28 : auto poSrcDS = m_inputDataset[0].GetDatasetRef(); 118 28 : CPLAssert(poSrcDS); 119 : 120 28 : if (m_format.empty()) 121 17 : m_format = IsCalledFromCommandLine() ? "text" : "json"; 122 : 123 56 : CPLStringList aosOptions; 124 : 125 28 : aosOptions.AddString("--cli"); 126 : 127 28 : if (m_format == "json") 128 : { 129 15 : aosOptions.AddString("-json"); 130 : } 131 : 132 28 : if (m_summaryOnly) 133 : { 134 4 : aosOptions.AddString("-summary"); 135 : } 136 24 : else if (m_listFeatures) 137 : { 138 4 : aosOptions.AddString("-features"); 139 : } 140 : 141 28 : if (!m_sql.empty()) 142 : { 143 3 : aosOptions.AddString("-sql"); 144 3 : aosOptions.AddString(m_sql.c_str()); 145 : } 146 28 : if (!m_where.empty()) 147 : { 148 2 : aosOptions.AddString("-where"); 149 2 : aosOptions.AddString(m_where.c_str()); 150 : } 151 28 : if (!m_dialect.empty()) 152 : { 153 2 : aosOptions.AddString("-dialect"); 154 2 : aosOptions.AddString(m_dialect.c_str()); 155 : } 156 28 : if (m_stdout) 157 : { 158 4 : aosOptions.AddString("-stdout"); 159 : } 160 28 : if (m_limit > 0) 161 : { 162 1 : aosOptions.AddString("-limit"); 163 1 : aosOptions.AddString(std::to_string(m_limit)); 164 : } 165 : 166 : // Must be last, as positional 167 28 : aosOptions.AddString("dummy"); 168 29 : for (const std::string &name : m_layerNames) 169 1 : aosOptions.AddString(name.c_str()); 170 : 171 28 : if (m_layerNames.empty()) 172 : { 173 27 : aosOptions.AddString("-al"); 174 : } 175 : 176 : GDALVectorInfoOptions *psInfo = 177 28 : GDALVectorInfoOptionsNew(aosOptions.List(), nullptr); 178 : 179 28 : char *ret = GDALVectorInfo(GDALDataset::ToHandle(poSrcDS), psInfo); 180 28 : GDALVectorInfoOptionsFree(psInfo); 181 28 : if (!ret) 182 0 : return false; 183 : 184 28 : m_output = ret; 185 28 : CPLFree(ret); 186 : 187 28 : return true; 188 : } 189 : 190 : GDALVectorInfoAlgorithmStandalone::~GDALVectorInfoAlgorithmStandalone() = 191 : default; 192 : 193 : //! @endcond