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