• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 #include "profile_data_rdb_adapter.h"
17 
18 #include <mutex>
19 #include <chrono>
20 #include <unistd.h>
21 
22 #include "rdb_errno.h"
23 
24 #include "distributed_device_profile_constants.h"
25 #include "distributed_device_profile_errors.h"
26 #include "distributed_device_profile_log.h"
27 #include "profile_utils.h"
28 
29 namespace OHOS {
30 namespace DistributedDeviceProfile {
31 IMPLEMENT_SINGLE_INSTANCE(ProfileDataRdbAdapter);
32 using namespace std::chrono_literals;
33 namespace {
34     const std::set<std::string> TABLES = {
35         "device_profile",
36         "service_profile",
37         "characteristic_profile",
38         "device_icon_info",
39         "product_info"
40     };
41     const std::string TAG = "ProfileDatardbAdapter";
42 }
43 
Init()44 int32_t ProfileDataRdbAdapter::Init()
45 {
46     int32_t retryTimes = RDB_INIT_MAX_TIMES;
47     while (retryTimes > 0) {
48         if (GetRDBPtr() == DP_SUCCESS) {
49             HILOGI("ProfileDatardbAdapter init success");
50             return DP_SUCCESS;
51         }
52         usleep(RDB_INIT_INTERVAL_TIME);
53         retryTimes--;
54     }
55     HILOGE("ProfileDatardbAdapter init failed");
56     return DP_RDBADAPTER_INIT_FAIL;
57 }
58 
UnInit()59 int32_t ProfileDataRdbAdapter::UnInit()
60 {
61     HILOGI("ProfileDatardbAdapter unInit");
62     {
63         std::lock_guard<std::mutex> lock(ProfileDataRdbAdapterMtx_);
64         store_ = nullptr;
65     }
66     return DP_SUCCESS;
67 }
68 
Put(int64_t & outRowId,const std::string & table,const ValuesBucket & values)69 int32_t ProfileDataRdbAdapter::Put(int64_t& outRowId, const std::string& table, const ValuesBucket& values)
70 {
71     if (TABLES.find(table) == TABLES.end()) {
72         HILOGE("table does not exist");
73         return DP_RDBADAPTER_TABLE_NOT_EXIST;
74     }
75     {
76         std::lock_guard<std::mutex> lock(ProfileDataRdbAdapterMtx_);
77         if (store_ == nullptr) {
78             HILOGE("RDBStore_ is null");
79             return DP_RDB_DB_PTR_NULL;
80         }
81         int32_t ret = store_->Insert(outRowId, table, values);
82         if (ret == E_SQLITE_CORRUPT) {
83             HILOGE("database corrupt ret:%{public}d", ret);
84             int32_t restoreRet = store_->Restore("");
85             if (restoreRet != E_OK) {
86                 HILOGE("Restore failed restoreRet:%{public}d", restoreRet);
87                 return DP_RDB_DATABASE_RESTORE_FAIL;
88             }
89             ret = store_->Insert(outRowId, table, values);
90         }
91         if (ret != E_OK) {
92             HILOGE("ProfileDatardbAdapter put failed ret:%{public}d", ret);
93             return DP_RDBADAPTER_PUT_FAIL;
94         }
95     }
96     return DP_SUCCESS;
97 }
98 
Delete(int32_t & deleteRows,const std::string & table,const std::string & whereClause,const std::vector<ValueObject> & bindArgs)99 int32_t ProfileDataRdbAdapter::Delete(int32_t& deleteRows, const std::string& table, const std::string& whereClause,
100     const std::vector<ValueObject>& bindArgs)
101 {
102     if (TABLES.find(table) == TABLES.end()) {
103         HILOGE("table does not exist");
104         return DP_RDBADAPTER_TABLE_NOT_EXIST;
105     }
106     {
107         std::lock_guard<std::mutex> lock(ProfileDataRdbAdapterMtx_);
108         if (store_ == nullptr) {
109             HILOGE("RDBStore_ is null");
110             return DP_RDB_DB_PTR_NULL;
111         }
112         int32_t ret = store_->Delete(deleteRows, table, whereClause, bindArgs);
113         if (ret == E_SQLITE_CORRUPT) {
114             HILOGE("database corrupt ret:%{public}d", ret);
115             int32_t restoreRet = store_->Restore("");
116             if (restoreRet != E_OK) {
117                 HILOGE("Restore failed restoreRet:%{public}d", restoreRet);
118                 return DP_RDB_DATABASE_RESTORE_FAIL;
119             }
120             ret = store_->Delete(deleteRows, table, whereClause, bindArgs);
121         }
122         if (ret != E_OK) {
123             HILOGE("ProfileDatardbAdapter delete failed ret:%{public}d", ret);
124             return DP_RDBADAPTER_DELETE_FAIL;
125         }
126     }
127     return DP_SUCCESS;
128 }
129 
Update(int32_t & changedRows,const std::string & table,const ValuesBucket & values,const std::string & whereClause,const std::vector<ValueObject> & bindArgs)130 int32_t ProfileDataRdbAdapter::Update(int32_t& changedRows, const std::string& table, const ValuesBucket& values,
131     const std::string& whereClause, const std::vector<ValueObject>& bindArgs)
132 {
133     if (TABLES.find(table) == TABLES.end()) {
134         HILOGE("table does not exist");
135         return DP_RDBADAPTER_TABLE_NOT_EXIST;
136     }
137     {
138         std::lock_guard<std::mutex> lock(ProfileDataRdbAdapterMtx_);
139         if (store_ == nullptr) {
140             HILOGE("RDBStore_ is null");
141             return DP_RDB_DB_PTR_NULL;
142         }
143         int32_t ret = store_->Update(changedRows, table, values, whereClause, bindArgs);
144         if (ret == E_SQLITE_CORRUPT) {
145             HILOGE("database corrupt ret:%{public}d", ret);
146             int32_t restoreRet = store_->Restore("");
147             if (restoreRet != E_OK) {
148                 HILOGE("Restore failed restoreRet:%{public}d", restoreRet);
149                 return DP_RDB_DATABASE_RESTORE_FAIL;
150             }
151             ret = store_->Update(changedRows, table, values, whereClause, bindArgs);
152         }
153         if (ret != E_OK) {
154             HILOGE("ProfileDatardbAdapter update failed ret:%{public}d", ret);
155             return DP_RDBADAPTER_UPDATE_FAIL;
156         }
157     }
158     return DP_SUCCESS;
159 }
160 
Get(const std::string & sql,const std::vector<ValueObject> & args)161 std::shared_ptr<ResultSet> ProfileDataRdbAdapter::Get(const std::string& sql, const std::vector<ValueObject>& args)
162 {
163     std::shared_ptr<ResultSet> resultSet = nullptr;
164     {
165         std::lock_guard<std::mutex> lock(ProfileDataRdbAdapterMtx_);
166         if (store_ == nullptr) {
167             HILOGE("RDBStore_ is null");
168             return nullptr;
169         }
170         resultSet = store_->QueryByStep(sql, args);
171         if (resultSet == nullptr) {
172             HILOGE("resultSet is null");
173             return nullptr;
174         }
175         int32_t rowCount = ROWCOUNT_INIT;
176         int32_t ret = resultSet->GetRowCount(rowCount);
177         if (ret == E_SQLITE_CORRUPT) {
178             HILOGE("database corrupt ret:%{public}d", ret);
179             resultSet->Close();
180             ret = store_->Restore("");
181             if (ret != E_OK) {
182                 HILOGE("Restore failed ret:%{public}d", ret);
183                 return nullptr;
184             }
185             resultSet = store_->QueryByStep(sql, args);
186         }
187     }
188     return resultSet;
189 }
190 
GetRDBPtr()191 int32_t ProfileDataRdbAdapter::GetRDBPtr()
192 {
193     int32_t version = RDB_VERSION_5_1;
194     ProfileDataOpenCallback helper;
195     RdbStoreConfig config(PROFILE_DATA_RDB_PATH + PROFILE_DATA_DATABASE_NAME);
196     config.SetSecurityLevel(SecurityLevel::S2);
197     config.SetHaMode(HAMode::MAIN_REPLICA);
198     config.SetAllowRebuild(true);
199     int32_t errCode = E_OK;
200     {
201         std::lock_guard<std::mutex> lock(ProfileDataRdbAdapterMtx_);
202         store_ = RdbHelper::GetRdbStore(config, version, helper, errCode);
203         if (store_ == nullptr) {
204             HILOGE("RDBStore_ is null");
205             return DP_RDB_DB_PTR_NULL;
206         }
207         NativeRdb::RebuiltType rebuiltType = NativeRdb::RebuiltType::NONE;
208         errCode = store_->GetRebuilt(rebuiltType);
209         if (errCode != E_OK) {
210             HILOGE("getRDBPtr failed errCode:%{public}d", errCode);
211             return DP_GET_RDBSTORE_FAIL;
212         }
213         if (rebuiltType == NativeRdb::RebuiltType::REBUILT) {
214             HILOGE("database corrupt");
215             int32_t restoreRet = store_->Restore("");
216             if (restoreRet != E_OK) {
217                 HILOGE("Restore failed restoreRet:%{public}d", restoreRet);
218                 return DP_RDB_DATABASE_RESTORE_FAIL;
219             }
220         }
221     }
222     return DP_SUCCESS;
223 }
224 
IsInit()225 bool ProfileDataRdbAdapter::IsInit()
226 {
227     {
228         std::lock_guard<std::mutex> lock(ProfileDataRdbAdapterMtx_);
229         if (store_ == nullptr) {
230             return false;
231         }
232     }
233     return true;
234 }
235 
CreateTable(const std::string & sql)236 int32_t ProfileDataRdbAdapter::CreateTable(const std::string& sql)
237 {
238     {
239         std::lock_guard<std::mutex> lock(ProfileDataRdbAdapterMtx_);
240         if (store_ == nullptr) {
241             HILOGE("RDBStore_ is null");
242             return DP_RDB_DB_PTR_NULL;
243         }
244         if (store_->ExecuteSql(sql) != E_OK) {
245             HILOGE("ProfileDatardbAdapter create table failed");
246             return DP_RDBADAPTER_TABLE_NOT_EXIST;
247         }
248     }
249     return DP_SUCCESS;
250 }
251 
OnCreate(RdbStore & store)252 int32_t ProfileDataOpenCallback::OnCreate(RdbStore& store)
253 {
254     HILOGI("rdbStore create");
255     return NativeRdb::E_OK;
256 }
257 
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)258 int32_t ProfileDataOpenCallback::OnUpgrade(RdbStore& store, int oldVersion, int newVersion)
259 {
260     HILOGI("rdbStore upgrade : %{public}d -> %{public}d", oldVersion, newVersion);
261     if (oldVersion == RDB_VERSION && newVersion == RDB_VERSION_5_1) {
262         return UpdateFromVer1To2(store);
263     }
264     return NativeRdb::E_OK;
265 }
266 
CheckAndAlterTable(RdbStore & store,const RdbTableAlterInfo & info)267 int32_t ProfileDataOpenCallback::CheckAndAlterTable(RdbStore& store, const RdbTableAlterInfo& info)
268 {
269     int32_t ret = RET_INIT;
270     bool isExistColumn = ProfileUtils::IsExistColumn(store, info.tabName, info.colName, info.colType, ret);
271     if (ret != DP_SUCCESS) {
272         HILOGE("IsExistColumn failed,reason:%{public}d", ret);
273         return ret;
274     }
275     if (isExistColumn) {
276         HILOGW("already exist,tableName:%{public}s,columnName:%{public}s,columnType:%{public}s",
277             ProfileUtils::GetAnonyString(info.tabName).c_str(), info.colName.c_str(), info.colType.c_str());
278         return DP_SUCCESS;
279     }
280     ret = store.ExecuteSql(info.sql);
281     if (ret != NativeRdb::E_OK) {
282         HILOGE("ExecuteSql failed,reason:%{public}d", ret);
283         return ret;
284     }
285     HILOGI("succeed,tableName:%{public}s,columnName:%{public}s,columnType:%{public}s",
286         ProfileUtils::GetAnonyString(info.tabName).c_str(), info.colName.c_str(), info.colType.c_str());
287     return DP_SUCCESS;
288 }
289 
UpdateFromVer1To2(RdbStore & store)290 int32_t ProfileDataOpenCallback::UpdateFromVer1To2(RdbStore& store)
291 {
292     RdbTableAlterInfo deviceProfileAddProductNameColumn {
293         .tabName = DEVICE_PROFILE_TABLE,
294         .colName = PRODUCT_NAME,
295         .colType = RDB_TYPE_TEXT,
296         .sql = ALTER_TABLE_DP_ADD_COLUMN_PRODUCT_NAME_SQL
297     };
298     int32_t ret = CheckAndAlterTable(store, deviceProfileAddProductNameColumn);
299     if (ret != DP_SUCCESS) {
300         HILOGE("CheckAndAlterTable failed,reason:%{public}d,tableName:%{public}s,columnName:%{public}s", ret,
301             ProfileUtils::GetAnonyString(deviceProfileAddProductNameColumn.tabName).c_str(),
302             deviceProfileAddProductNameColumn.colName.c_str());
303         return ret;
304     }
305     RdbTableAlterInfo deviceProfileRenameInterModelColumn {
306         .tabName = DEVICE_PROFILE_TABLE,
307         .colName = INTERNAL_MODEL,
308         .colType = RDB_TYPE_TEXT,
309         .sql = ALTER_TABLE_DP_RENAME_COLUMN_INTERNAL_MODEL_SQL
310     };
311     ret = CheckAndAlterTable(store, deviceProfileRenameInterModelColumn);
312     if (ret != DP_SUCCESS) {
313         HILOGE("CheckAndAlterTable failed,reason:%{public}d,tableName:%{public}s,columnName:%{public}s", ret,
314             ProfileUtils::GetAnonyString(deviceProfileRenameInterModelColumn.tabName).c_str(),
315             deviceProfileRenameInterModelColumn.colName.c_str());
316         return ret;
317     }
318     RdbTableAlterInfo deviceIconInfoAddInterModelColumn {
319         .tabName = DEVICE_ICON_INFO_TABLE,
320         .colName = INTERNAL_MODEL,
321         .colType = RDB_TYPE_TEXT,
322         .sql = ALTER_TABLE_DEVICE_ICON_INFO_ADD_COLUMN_INTENAL_MODEL_SQL
323     };
324     ret = CheckAndAlterTable(store, deviceIconInfoAddInterModelColumn);
325     if (ret != DP_SUCCESS) {
326         HILOGE("CheckAndAlterTable failed,reason:%{public}d,tableName:%{public}s,columnName:%{public}s", ret,
327             ProfileUtils::GetAnonyString(deviceIconInfoAddInterModelColumn.tabName).c_str(),
328             deviceIconInfoAddInterModelColumn.colName.c_str());
329         return ret;
330     }
331     HILOGI("succeed");
332     return NativeRdb::E_OK;
333 }
334 } // namespace DistributedDeviceProfile
335 } // namespace OHOS
336