Coverage Report

Created: 2026-07-25 06:50

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