1 /*
2 * Copyright (c) 2023-2024 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
16 #define FUSE_USE_VERSION 34
17
18 #include "clouddisk_rdb_utils.h"
19
20 #include <fuse_lowlevel.h>
21
22 #include "utils_log.h"
23 #include "dfs_error.h"
24 #include "clouddisk_db_const.h"
25 #include "file_column.h"
26 #include "result_set.h"
27
28 namespace OHOS::FileManagement::CloudDisk {
29 using namespace std;
30 using namespace NativeRdb;
31
32 static const int32_t LOCAL_ID_OFFSET = 100;
33 static const uint32_t STAT_MODE_REG = 0660;
34 static const uint32_t STAT_MODE_DIR = 0771;
35
GetInt(const string &key, int32_t &val, const shared_ptr<ResultSet> resultSet)36 int32_t CloudDiskRdbUtils::GetInt(const string &key, int32_t &val,
37 const shared_ptr<ResultSet> resultSet)
38 {
39 if (resultSet == nullptr) {
40 LOGE("result set is nullptr");
41 return E_RDB;
42 }
43 int32_t index;
44 int32_t err = resultSet->GetColumnIndex(key, index);
45 if (err != E_OK) {
46 LOGE("result set get column index err %{public}d", err);
47 return E_RDB;
48 }
49 err = resultSet->GetInt(index, val);
50 if (err != 0) {
51 LOGE("result set get int err %{public}d", err);
52 return E_RDB;
53 }
54 return E_OK;
55 }
56
GetLong(const string &key, int64_t &val, const shared_ptr<ResultSet> resultSet)57 int32_t CloudDiskRdbUtils::GetLong(const string &key, int64_t &val,
58 const shared_ptr<ResultSet> resultSet)
59 {
60 if (resultSet == nullptr) {
61 LOGE("result set is nullptr");
62 return E_RDB;
63 }
64 int32_t index;
65 int32_t err = resultSet->GetColumnIndex(key, index);
66 if (err != E_OK) {
67 LOGE("result set get column index err %{public}d", err);
68 return E_RDB;
69 }
70 err = resultSet->GetLong(index, val);
71 if (err != 0) {
72 LOGE("result set get int err %{public}d", err);
73 return E_RDB;
74 }
75 return E_OK;
76 }
77
GetString(const string &key, string &val, const shared_ptr<ResultSet> resultSet)78 int32_t CloudDiskRdbUtils::GetString(const string &key, string &val,
79 const shared_ptr<ResultSet> resultSet)
80 {
81 if (resultSet == nullptr) {
82 LOGE("result set is nullptr");
83 return E_RDB;
84 }
85 int32_t index;
86 int32_t err = resultSet->GetColumnIndex(key, index);
87 if (err != E_OK) {
88 LOGE("result set get column index err %{public}d", err);
89 return E_RDB;
90 }
91 err = resultSet->GetString(index, val);
92 if (err != 0) {
93 LOGE("result set get string err %{public}d", err);
94 return E_RDB;
95 }
96 return E_OK;
97 }
98
FillFileInfo(const RowEntity &rowEntity, CloudDiskFileInfo &info)99 static void FillFileInfo(const RowEntity &rowEntity, CloudDiskFileInfo &info)
100 {
101 rowEntity.Get(FileColumn::FILE_NAME).GetString(info.name);
102 rowEntity.Get(FileColumn::CLOUD_ID).GetString(info.cloudId);
103 rowEntity.Get(FileColumn::PARENT_CLOUD_ID).GetString(info.parentCloudId);
104 int32_t int_variable;
105 rowEntity.Get(FileColumn::POSITION).GetInt(int_variable);
106 info.location = static_cast<uint32_t>(int_variable);
107 int64_t long_variable;
108 rowEntity.Get(FileColumn::FILE_SIZE).GetLong(long_variable);
109 info.size = static_cast<unsigned long long>(long_variable);
110 rowEntity.Get(FileColumn::FILE_TIME_ADDED).GetLong(long_variable);
111 info.atime = static_cast<unsigned long long>(long_variable);
112 rowEntity.Get(FileColumn::META_TIME_EDITED).GetLong(long_variable);
113 info.ctime = static_cast<unsigned long long>(long_variable);
114 rowEntity.Get(FileColumn::FILE_TIME_EDITED).GetLong(long_variable);
115 info.mtime = static_cast<unsigned long long>(long_variable);
116 rowEntity.Get(FileColumn::IS_DIRECTORY).GetInt(int_variable);
117 info.IsDirectory = (int_variable == DIRECTORY);
118 info.mode = (info.IsDirectory) ? (S_IFDIR | STAT_MODE_DIR) : (S_IFREG | STAT_MODE_REG);
119 rowEntity.Get(FileColumn::ROW_ID).GetLong(long_variable);
120 info.localId = static_cast<long long>(long_variable) + LOCAL_ID_OFFSET;
121 }
122
ResultSetToFileInfo(const shared_ptr<ResultSet> resultSet, CloudDiskFileInfo &info)123 int32_t CloudDiskRdbUtils::ResultSetToFileInfo(const shared_ptr<ResultSet> resultSet,
124 CloudDiskFileInfo &info)
125 {
126 if (resultSet == nullptr) {
127 LOGE("result set is nullptr");
128 return E_RDB;
129 }
130 if (resultSet->GoToNextRow() != E_OK) {
131 LOGE("result set to file info go to next row failed");
132 return E_RDB;
133 }
134 RowEntity rowEntity;
135 if (resultSet->GetRow(rowEntity) != E_OK) {
136 LOGE("result set to file info get row failed");
137 return E_RDB;
138 }
139 FillFileInfo(rowEntity, info);
140 return E_OK;
141 }
142
FuseDentryAlignSize(const char *name)143 size_t CloudDiskRdbUtils::FuseDentryAlignSize(const char *name)
144 {
145 return fuse_add_direntry({}, nullptr, 0, name, nullptr, 0);
146 }
147
ResultSetToFileInfos(const shared_ptr<ResultSet> resultSet, vector<CloudDiskFileInfo> &infos)148 int32_t CloudDiskRdbUtils::ResultSetToFileInfos(const shared_ptr<ResultSet> resultSet,
149 vector<CloudDiskFileInfo> &infos)
150 {
151 if (resultSet == nullptr) {
152 LOGE("result set is nullptr");
153 return E_RDB;
154 }
155 off_t nextOff = 0;
156 while (resultSet->GoToNextRow() == E_OK) {
157 CloudDiskFileInfo info;
158 GetString(FileColumn::FILE_NAME, info.name, resultSet);
159 int32_t isDirectory;
160 GetInt(FileColumn::IS_DIRECTORY, isDirectory, resultSet);
161 info.IsDirectory = (isDirectory == DIRECTORY);
162 info.mode = (info.IsDirectory) ? (S_IFDIR | STAT_MODE_DIR) : (S_IFREG | STAT_MODE_REG);
163 nextOff += FuseDentryAlignSize(info.name.c_str());
164 info.nextOff = nextOff;
165 infos.emplace_back(info);
166 }
167 return E_OK;
168 }
169 }