1 /*
2 * Copyright (c) 2025 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 #include "local_service_info_rdb_adapter.h"
17
18 #include <mutex>
19 #include <chrono>
20 #include <unistd.h>
21
22 #include "distributed_device_profile_constants.h"
23 #include "dp_services_constants.h"
24 #include "distributed_device_profile_errors.h"
25 #include "distributed_device_profile_log.h"
26 #include "rdb_errno.h"
27
28 namespace OHOS {
29 namespace DistributedDeviceProfile {
30 IMPLEMENT_SINGLE_INSTANCE(LocalServiceInfoRdbAdapter);
31 using namespace std::chrono_literals;
32 namespace {
33 const std::set<std::string> TABLES = {
34 "local_service_info"
35 };
36 const std::string TAG = "LocalServiceInfoRdbAdapter";
37 }
38
Init()39 int32_t LocalServiceInfoRdbAdapter::Init()
40 {
41 int32_t retryTimes = RDB_INIT_MAX_TIMES;
42 while (retryTimes > 0) {
43 if (GetRDBPtr() == DP_SUCCESS) {
44 HILOGI("LocalServiceInfoRdbAdapter init success");
45 return DP_SUCCESS;
46 }
47 usleep(RDB_INIT_INTERVAL_TIME);
48 retryTimes--;
49 }
50 HILOGE("LocalServiceInfoRdbAdapter init failed");
51 return DP_RDBADAPTER_INIT_FAIL;
52 }
53
UnInit()54 int32_t LocalServiceInfoRdbAdapter::UnInit()
55 {
56 HILOGI("LocalServiceInfoRdbAdapter unInit");
57 {
58 std::lock_guard<std::mutex> lock(LocalServiceInfoRdbAdapterMtx_);
59 store_ = nullptr;
60 }
61 return DP_SUCCESS;
62 }
63
Put(int64_t & outRowId,const std::string & table,const ValuesBucket & values)64 int32_t LocalServiceInfoRdbAdapter::Put(int64_t& outRowId, const std::string& table, const ValuesBucket& values)
65 {
66 if (TABLES.find(table) == TABLES.end()) {
67 HILOGE("table does not exist");
68 return DP_RDBADAPTER_TABLE_NOT_EXIST;
69 }
70 {
71 std::lock_guard<std::mutex> lock(LocalServiceInfoRdbAdapterMtx_);
72 if (store_ == nullptr) {
73 HILOGE("RDBStore_ is null");
74 return DP_RDB_DB_PTR_NULL;
75 }
76 int32_t ret = store_->Insert(outRowId, table, values);
77 if (ret == E_SQLITE_CORRUPT) {
78 HILOGE("database corrupt ret:%{public}d", ret);
79 int32_t restoreRet = store_->Restore("");
80 if (restoreRet != E_OK) {
81 HILOGE("Restore failed restoreRet:%{public}d", restoreRet);
82 return DP_RDB_DATABASE_RESTORE_FAIL;
83 }
84 ret = store_->Insert(outRowId, table, values);
85 }
86 if (ret != E_OK) {
87 HILOGE("LocalServiceInfoRdbAdapter put failed ret:%{public}d", ret);
88 return DP_RDBADAPTER_PUT_FAIL;
89 }
90 }
91 return DP_SUCCESS;
92 }
93
Delete(int32_t & deleteRows,const std::string & table,const std::string & whereClause,const std::vector<ValueObject> & bindArgs)94 int32_t LocalServiceInfoRdbAdapter::Delete(int32_t& deleteRows, const std::string& table,
95 const std::string& whereClause, const std::vector<ValueObject>& bindArgs)
96 {
97 if (TABLES.find(table) == TABLES.end()) {
98 HILOGE("table does not exist");
99 return DP_RDBADAPTER_TABLE_NOT_EXIST;
100 }
101 {
102 std::lock_guard<std::mutex> lock(LocalServiceInfoRdbAdapterMtx_);
103 if (store_ == nullptr) {
104 HILOGE("RDBStore_ is null");
105 return DP_RDB_DB_PTR_NULL;
106 }
107 int32_t ret = store_->Delete(deleteRows, table, whereClause, bindArgs);
108 if (ret == E_SQLITE_CORRUPT) {
109 HILOGE("database corrupt ret:%{public}d", ret);
110 int32_t restoreRet = store_->Restore("");
111 if (restoreRet != E_OK) {
112 HILOGE("Restore failed restoreRet:%{public}d", restoreRet);
113 return DP_RDB_DATABASE_RESTORE_FAIL;
114 }
115 ret = store_->Delete(deleteRows, table, whereClause, bindArgs);
116 }
117 if (ret != E_OK) {
118 HILOGE("LocalServiceInfoRdbAdapter delete failed ret:%{public}d", ret);
119 return DP_RDBADAPTER_DELETE_FAIL;
120 }
121 }
122 return DP_SUCCESS;
123 }
124
Update(int32_t & changedRows,const std::string & table,const ValuesBucket & values,const std::string & whereClause,const std::vector<ValueObject> & bindArgs)125 int32_t LocalServiceInfoRdbAdapter::Update(int32_t& changedRows, const std::string& table, const ValuesBucket& values,
126 const std::string& whereClause, const std::vector<ValueObject>& bindArgs)
127 {
128 if (TABLES.find(table) == TABLES.end()) {
129 HILOGE("table does not exist");
130 return DP_RDBADAPTER_TABLE_NOT_EXIST;
131 }
132 {
133 std::lock_guard<std::mutex> lock(LocalServiceInfoRdbAdapterMtx_);
134 if (store_ == nullptr) {
135 HILOGE("RDBStore_ is null");
136 return DP_RDB_DB_PTR_NULL;
137 }
138 int32_t ret = store_->Update(changedRows, table, values, whereClause, bindArgs);
139 if (ret == E_SQLITE_CORRUPT) {
140 HILOGE("database corrupt ret:%{public}d", ret);
141 int32_t restoreRet = store_->Restore("");
142 if (restoreRet != E_OK) {
143 HILOGE("Restore failed restoreRet:%{public}d", restoreRet);
144 return DP_RDB_DATABASE_RESTORE_FAIL;
145 }
146 ret = store_->Update(changedRows, table, values, whereClause, bindArgs);
147 }
148 if (ret != E_OK) {
149 HILOGE("LocalServiceInfoRdbAdapter update failed ret:%{public}d", ret);
150 return DP_RDBADAPTER_UPDATE_FAIL;
151 }
152 }
153 return DP_SUCCESS;
154 }
155
Get(const std::string & sql,const std::vector<ValueObject> & args)156 std::shared_ptr<ResultSet> LocalServiceInfoRdbAdapter::Get(const std::string& sql, const std::vector<ValueObject>& args)
157 {
158 std::shared_ptr<ResultSet> resultSet = nullptr;
159 {
160 std::lock_guard<std::mutex> lock(LocalServiceInfoRdbAdapterMtx_);
161 if (store_ == nullptr) {
162 HILOGE("RDBStore_ is null");
163 return nullptr;
164 }
165 resultSet = store_->QueryByStep(sql, args);
166 if (resultSet == nullptr) {
167 HILOGE("resultSet is null");
168 return nullptr;
169 }
170 int32_t rowCount = ROWCOUNT_INIT;
171 int32_t ret = resultSet->GetRowCount(rowCount);
172 if (ret == E_SQLITE_CORRUPT) {
173 HILOGE("database corrupt ret:%{public}d", ret);
174 resultSet->Close();
175 ret = store_->Restore("");
176 if (ret != E_OK) {
177 HILOGE("Restore failed ret:%{public}d", ret);
178 return nullptr;
179 }
180 resultSet = store_->QueryByStep(sql, args);
181 }
182 }
183 return resultSet;
184 }
185
GetRDBPtr()186 int32_t LocalServiceInfoRdbAdapter::GetRDBPtr()
187 {
188 int32_t version = RDB_VERSION;
189 LocalServiceInfoOpenCallback helper;
190 RdbStoreConfig config(LOCAL_SERVICE_INFO_RDB_PATH + LOCAL_SERVICE_INFO_DATABASE_NAME);
191 config.SetSecurityLevel(SecurityLevel::S2);
192 config.SetHaMode(HAMode::MAIN_REPLICA);
193 config.SetAllowRebuild(true);
194 int32_t errCode = E_OK;
195 {
196 std::lock_guard<std::mutex> lock(LocalServiceInfoRdbAdapterMtx_);
197 store_ = RdbHelper::GetRdbStore(config, version, helper, errCode);
198 if (store_ == nullptr) {
199 HILOGE("RDBStore_ is null");
200 return DP_RDB_DB_PTR_NULL;
201 }
202 NativeRdb::RebuiltType rebuiltType = NativeRdb::RebuiltType::NONE;
203 errCode = store_->GetRebuilt(rebuiltType);
204 if (errCode != E_OK) {
205 HILOGE("getRDBPtr failed errCode:%{public}d", errCode);
206 return DP_GET_RDBSTORE_FAIL;
207 }
208 if (rebuiltType == NativeRdb::RebuiltType::REBUILT) {
209 HILOGE("database corrupt");
210 int32_t restoreRet = store_->Restore("");
211 if (restoreRet != E_OK) {
212 HILOGE("Restore failed restoreRet:%{public}d", restoreRet);
213 return DP_RDB_DATABASE_RESTORE_FAIL;
214 }
215 }
216 }
217 return DP_SUCCESS;
218 }
219
IsInit()220 bool LocalServiceInfoRdbAdapter::IsInit()
221 {
222 if (store_ == nullptr) {
223 return false;
224 }
225 return true;
226 }
227
CreateTable(const std::string & sql)228 int32_t LocalServiceInfoRdbAdapter::CreateTable(const std::string& sql)
229 {
230 {
231 std::lock_guard<std::mutex> lock(LocalServiceInfoRdbAdapterMtx_);
232 if (store_ == nullptr) {
233 HILOGE("RDBStore_ is null");
234 return DP_RDB_DB_PTR_NULL;
235 }
236 if (store_->ExecuteSql(sql) != E_OK) {
237 HILOGE("LocalServiceInfoRdbAdapter create table failed");
238 return DP_RDBADAPTER_TABLE_NOT_EXIST;
239 }
240 }
241 return DP_SUCCESS;
242 }
243
OnCreate(RdbStore & store)244 int32_t LocalServiceInfoOpenCallback::OnCreate(RdbStore& store)
245 {
246 HILOGI("rdbStore create");
247 return NativeRdb::E_OK;
248 }
249
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)250 int32_t LocalServiceInfoOpenCallback::OnUpgrade(RdbStore& store, int oldVersion, int newVersion)
251 {
252 HILOGI("rdbStore upgrade");
253 return NativeRdb::E_OK;
254 }
255 } // namespace DistributedDeviceProfile
256 } // namespace OHOS
257