Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: GDAL
4 : * Purpose: gdal "dataset copy" subcommand
5 : * Author: Even Rouault <even dot rouault at spatialys.com>
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 2025, Even Rouault <even dot rouault at spatialys.com>
9 : *
10 : * SPDX-License-Identifier: MIT
11 : ****************************************************************************/
12 :
13 : #include "gdalalg_dataset_copy.h"
14 :
15 : #include "gdal.h"
16 : #include "gdal_priv.h"
17 :
18 : //! @cond Doxygen_Suppress
19 :
20 : #ifndef _
21 : #define _(x) (x)
22 : #endif
23 :
24 : /************************************************************************/
25 : /* GDALDatasetCopyRenameCommonAlgorithm() */
26 : /************************************************************************/
27 :
28 99 : GDALDatasetCopyRenameCommonAlgorithm::GDALDatasetCopyRenameCommonAlgorithm(
29 : const std::string &name, const std::string &description,
30 99 : const std::string &helpURL)
31 99 : : GDALAlgorithm(name, description, helpURL)
32 : {
33 99 : AddProgressArg(/* hidden = */ true);
34 :
35 : {
36 198 : auto &arg = AddArg("source", 0, _("Source dataset name"), &m_source)
37 99 : .SetPositional()
38 99 : .SetMinCharCount(0)
39 99 : .SetRequired();
40 99 : SetAutoCompleteFunctionForFilename(arg, 0);
41 : }
42 :
43 : {
44 : auto &arg = AddArg("destination", 0, _("Destination dataset name"),
45 198 : &m_destination)
46 99 : .SetPositional()
47 99 : .SetMinCharCount(0)
48 99 : .SetRequired();
49 99 : SetAutoCompleteFunctionForFilename(arg, 0);
50 : }
51 :
52 99 : AddOverwriteArg(&m_overwrite);
53 :
54 : {
55 : auto &arg =
56 198 : AddArg("format", 'f', _("Dataset format"), &m_format)
57 297 : .AddMetadataItem(GAAMDI_REQUIRED_CAPABILITIES, {GDAL_DCAP_OPEN})
58 99 : .SetCategory(GAAC_ADVANCED);
59 2 : arg.AddValidationAction([this, &arg]()
60 101 : { return ValidateFormat(arg, false, false); });
61 : arg.SetAutoCompleteFunction(
62 1 : [&arg](const std::string &)
63 : {
64 : return GDALAlgorithm::FormatAutoCompleteFunction(arg, false,
65 1 : false);
66 99 : });
67 : }
68 99 : }
69 :
70 : /************************************************************************/
71 : /* GDALDatasetCopyRenameCommonAlgorithm::RunImpl() */
72 : /************************************************************************/
73 :
74 12 : bool GDALDatasetCopyRenameCommonAlgorithm::RunImpl(GDALProgressFunc, void *)
75 : {
76 12 : const char *pszType = "";
77 12 : GDALDriver *poDriver = nullptr;
78 12 : if (GDALDoesFileOrDatasetExist(m_destination.c_str(), &pszType, &poDriver))
79 : {
80 3 : if (!m_overwrite)
81 : {
82 1 : ReportError(CE_Failure, CPLE_AppDefined,
83 : "%s '%s' already exists. Specify the --overwrite "
84 : "option to overwrite it.",
85 : pszType, m_destination.c_str());
86 1 : return false;
87 : }
88 2 : else if (EQUAL(pszType, "File"))
89 : {
90 1 : VSIUnlink(m_destination.c_str());
91 : }
92 1 : else if (EQUAL(pszType, "Directory"))
93 : {
94 : // We don't want the user to accidentally erase a non-GDAL dataset
95 1 : ReportError(CE_Failure, CPLE_AppDefined,
96 : "Directory '%s' already exists, but is not "
97 : "recognized as a valid GDAL dataset. "
98 : "Please manually delete it before retrying",
99 : m_destination.c_str());
100 1 : return false;
101 : }
102 0 : else if (poDriver)
103 : {
104 0 : CPLStringList aosDrivers;
105 0 : aosDrivers.AddString(poDriver->GetDescription());
106 0 : GDALDriver::QuietDelete(m_destination.c_str(), aosDrivers.List());
107 : }
108 : }
109 :
110 10 : GDALDriverH hDriver = nullptr;
111 10 : if (!m_format.empty())
112 1 : hDriver = GDALGetDriverByName(m_format.c_str());
113 10 : if (GetName() == GDALDatasetCopyAlgorithm::NAME)
114 : {
115 6 : return GDALCopyDatasetFiles(hDriver, m_destination.c_str(),
116 6 : m_source.c_str()) == CE_None;
117 : }
118 : else
119 : {
120 4 : return GDALRenameDataset(hDriver, m_destination.c_str(),
121 4 : m_source.c_str()) == CE_None;
122 : }
123 : }
124 :
125 : /************************************************************************/
126 : /* GDALDatasetCopyAlgorithm::GDALDatasetCopyAlgorithm() */
127 : /************************************************************************/
128 :
129 52 : GDALDatasetCopyAlgorithm::GDALDatasetCopyAlgorithm()
130 52 : : GDALDatasetCopyRenameCommonAlgorithm(NAME, DESCRIPTION, HELP_URL)
131 : {
132 52 : }
133 :
134 : GDALDatasetCopyAlgorithm::~GDALDatasetCopyAlgorithm() = default;
135 :
136 : //! @endcond
|