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