1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "utils/database_utils.h"
16
17 #include "constant.h"
18 #include "datashare_errno.h"
19 #include "fetch_result.h"
20 #include "media_column.h"
21 #include "media_file_uri.h"
22 #include "media_file_utils.h"
23 #include "medialibrary_db_const.h"
24 #include "medialibrary_errno.h"
25 #include "result_set_utils.h"
26 #include "utils/constant_utils.h"
27 #include "utils/db_const.h"
28
29 namespace OHOS {
30 namespace Media {
31 namespace MediaTool {
Dump(const DumpOpt & opt,const std::shared_ptr<FetchResult<FileAsset>> & resultSet)32 bool DatabaseUtils::Dump(const DumpOpt &opt, const std::shared_ptr<FetchResult<FileAsset>> &resultSet)
33 {
34 if (resultSet == nullptr) {
35 return true;
36 }
37 return DatabaseUtils::Dump(opt, resultSet->GetDataShareResultSet());
38 }
39
Dump(const DumpOpt & opt,const std::shared_ptr<DataShare::DataShareResultSet> & resultSet)40 bool DatabaseUtils::Dump(const DumpOpt &opt, const std::shared_ptr<DataShare::DataShareResultSet> &resultSet)
41 {
42 if (resultSet == nullptr) {
43 return true;
44 }
45 std::vector<ColumnInfo> columnInfos;
46 int32_t err = GetColumnInfo(opt, resultSet, columnInfos);
47 if (err != NativeRdb::E_OK) {
48 return false;
49 }
50 if (opt.isPrintFormTitle) {
51 printf("%s\n", TitleToStr(opt, columnInfos).c_str());
52 }
53 if (opt.count <= 0) {
54 return true;
55 }
56 int32_t ret = resultSet->GoToFirstRow();
57 if (ret != E_OK) {
58 printf("%s goto first row failed. ret:%d.\n", STR_FAIL.c_str(), ret);
59 return false;
60 }
61 for (int32_t row = 0; row < opt.count; row++) {
62 ret = resultSet->GoToRow(row);
63 if (ret != E_OK) {
64 printf("%s goto row failed. ret:%d, row:%d.\n", STR_FAIL.c_str(), ret, row);
65 return false;
66 }
67 std::string str;
68 ret = RowToStr(opt, resultSet, columnInfos, str);
69 if (ret != E_OK) {
70 printf("%s row to string failed. ret:%d\n", STR_FAIL.c_str(), ret);
71 return false;
72 }
73 printf("%s\n", str.c_str());
74 }
75 return true;
76 }
77
TitleToStr(const DumpOpt & opt,const std::vector<ColumnInfo> & columnInfos)78 std::string DatabaseUtils::TitleToStr(const DumpOpt &opt, const std::vector<ColumnInfo> &columnInfos)
79 {
80 std::string str;
81 for (size_t index = 0; index < columnInfos.size(); index++) {
82 auto &columnInfo = columnInfos[index];
83 std::string split = (index == 0) ? "" : opt.split;
84 str.append(split + columnInfo.name);
85 }
86 return str;
87 }
88
RowToStr(const DumpOpt & opt,const std::shared_ptr<DataShare::DataShareResultSet> & resultSet,const std::vector<ColumnInfo> & columnInfos,std::string & rowStr)89 int DatabaseUtils::RowToStr(const DumpOpt &opt, const std::shared_ptr<DataShare::DataShareResultSet> &resultSet,
90 const std::vector<ColumnInfo> &columnInfos, std::string &rowStr)
91 {
92 rowStr.clear();
93 if (resultSet == nullptr) {
94 return DataShare::E_ERROR;
95 }
96 for (size_t index = 0; index < columnInfos.size(); index++) {
97 auto &columnInfo = columnInfos[index];
98 std::string value;
99 int status = FieldToStr(opt, columnInfo, resultSet, value);
100 if (status != DataShare::E_OK) {
101 return DataShare::E_ERROR;
102 }
103 std::string split = (index == 0) ? "" : opt.split;
104 rowStr.append(split + value);
105 }
106 return DataShare::E_OK;
107 }
108
GetApi10Uri(const std::string & path,const std::string & displayName,int32_t mediaType,int32_t fileId)109 static std::string GetApi10Uri(const std::string &path, const std::string &displayName,
110 int32_t mediaType, int32_t fileId)
111 {
112 if (path.empty() || displayName.empty() || mediaType < 0) {
113 printf("param invalid, filePath %s or displayName %s invalid failed.\n",
114 path.c_str(), displayName.c_str());
115 return "";
116 }
117 string extrUri = MediaFileUtils::GetExtraUri(displayName, path);
118 return MediaFileUtils::GetUriByExtrConditions(ML_FILE_URI_PREFIX +
119 MediaFileUri::GetMediaTypeUri(static_cast<MediaType>(mediaType), MEDIA_API_VERSION_V10) + "/",
120 to_string(fileId), extrUri);
121 }
122
GetStrFromResultSet(const std::string & name,ResultSetDataType type,const std::shared_ptr<DataShare::DataShareResultSet> & resultSet,std::string & str)123 static int32_t GetStrFromResultSet(const std::string &name, ResultSetDataType type,
124 const std::shared_ptr<DataShare::DataShareResultSet> &resultSet, std::string &str)
125 {
126 if (name == MEDIA_DATA_DB_URI) {
127 int32_t id = get<int32_t>(ResultSetUtils::GetValFromColumn(MediaColumn::MEDIA_ID, resultSet,
128 ResultSetDataType::TYPE_INT32));
129 int32_t mediaType = get<int32_t>(ResultSetUtils::GetValFromColumn(MediaColumn::MEDIA_TYPE, resultSet,
130 ResultSetDataType::TYPE_INT32));
131 std::string path = get<std::string>(ResultSetUtils::GetValFromColumn(MediaColumn::MEDIA_FILE_PATH,
132 resultSet, ResultSetDataType::TYPE_STRING));
133 std::string displayName = get<std::string>(ResultSetUtils::GetValFromColumn(MediaColumn::MEDIA_NAME,
134 resultSet, ResultSetDataType::TYPE_STRING));
135 str = GetApi10Uri(path, displayName, mediaType, id);
136 return DataShare::E_OK;
137 }
138 switch (type) {
139 case ResultSetDataType::TYPE_STRING: {
140 str = get<std::string>(ResultSetUtils::GetValFromColumn(name, resultSet, type));
141 break;
142 }
143 case ResultSetDataType::TYPE_INT32: {
144 int32_t int32Value = get<int32_t>(ResultSetUtils::GetValFromColumn(name, resultSet, type));
145 str = std::to_string(int32Value);
146 break;
147 }
148 case ResultSetDataType::TYPE_INT64: {
149 int64_t int64Value = get<int64_t>(ResultSetUtils::GetValFromColumn(name, resultSet, type));
150 str = std::to_string(int64Value);
151 break;
152 }
153 case ResultSetDataType::TYPE_DOUBLE: {
154 double doubleValue = get<double>(ResultSetUtils::GetValFromColumn(name, resultSet, type));
155 str = std::to_string(doubleValue);
156 break;
157 }
158 default: {
159 return DataShare::E_ERROR;
160 }
161 }
162 return DataShare::E_OK;
163 }
164
FieldToStr(const DumpOpt & opt,const ColumnInfo & columnInfo,const std::shared_ptr<DataShare::DataShareResultSet> & resultSet,std::string & value)165 int DatabaseUtils::FieldToStr(const DumpOpt &opt, const ColumnInfo &columnInfo,
166 const std::shared_ptr<DataShare::DataShareResultSet> &resultSet, std::string &value)
167 {
168 value.clear();
169 if (resultSet == nullptr) {
170 return DataShare::E_ERROR;
171 }
172 bool isNull = false;
173 int status = resultSet->IsColumnNull(columnInfo.index, isNull);
174 if ((status == DataShare::E_OK) && isNull) {
175 value = "null";
176 return DataShare::E_OK;
177 }
178 std::string strValue;
179 status = GetStrFromResultSet(columnInfo.name, columnInfo.type, resultSet, strValue);
180 if (status != DataShare::E_OK) {
181 printf("%s field to string failed. status:%d, type:%d, name:%s.\n", STR_FAIL.c_str(),
182 status, columnInfo.type, columnInfo.name.c_str());
183 return status;
184 }
185 value = (columnInfo.type == ResultSetDataType::TYPE_STRING) ? opt.delimiter + strValue + opt.delimiter : strValue;
186 return DataShare::E_OK;
187 }
188
GetColumnInfo(const DumpOpt & opt,const std::shared_ptr<DataShare::DataShareResultSet> & resultSet,std::vector<ColumnInfo> & columnInfos)189 int32_t DatabaseUtils::GetColumnInfo(const DumpOpt &opt,
190 const std::shared_ptr<DataShare::DataShareResultSet> &resultSet, std::vector<ColumnInfo> &columnInfos)
191 {
192 if (resultSet == nullptr) {
193 return Media::E_ERR;
194 }
195 std::vector<std::string> names;
196 if (opt.columns.empty()) {
197 int32_t err = resultSet->GetAllColumnNames(names);
198 if (err != NativeRdb::E_OK) {
199 printf("%s get all column names failed. err:%d.\n", STR_FAIL.c_str(), err);
200 return err;
201 }
202 } else {
203 names = opt.columns;
204 }
205 for (const auto &name : names) {
206 ColumnInfo columnInfo;
207 columnInfo.name = name;
208 if (name != MEDIA_DATA_DB_URI) {
209 int32_t err = resultSet->GetColumnIndex(name, columnInfo.index);
210 if (err != NativeRdb::E_OK) {
211 printf("%s get column index failed. err:%d, name:%s.\n", STR_FAIL.c_str(), err, name.c_str());
212 return err;
213 }
214 if (RESULT_TYPE_MAP.count(name) <= 0) {
215 printf("%s please add %s into RESULT_TYPE_MAP.\n", STR_WARN.c_str(), name.c_str());
216 continue;
217 }
218 } else {
219 int32_t err = resultSet->GetColumnIndex(MediaColumn::MEDIA_ID, columnInfo.index);
220 if (err != NativeRdb::E_OK) {
221 printf("%s get column index failed. err:%d, name:%s.\n", STR_FAIL.c_str(), err, name.c_str());
222 return err;
223 }
224 }
225 columnInfo.type = RESULT_TYPE_MAP.at(name);
226 columnInfos.push_back(columnInfo);
227 }
228 return NativeRdb::E_OK;
229 }
230 } // namespace MediaTool
231 } // namespace Media
232 } // namespace OHOS
233