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 #define LOG_TAG "RdbAdaptor"
16 #include "rdb_delegate.h"
17
18 #include "crypto_manager.h"
19 #include "device_manager_adapter.h"
20 #include "metadata/meta_data_manager.h"
21 #include "metadata/store_meta_data.h"
22 #include "metadata/secret_key_meta_data.h"
23 #include "resultset_json_formatter.h"
24 #include "log_print.h"
25 #include "rdb_utils.h"
26 #include "scheduler_manager.h"
27 #include "utils/anonymous.h"
28
29 namespace OHOS::DataShare {
30 constexpr static int32_t MAX_RESULTSET_COUNT = 16;
31 std::atomic<int32_t> RdbDelegate::resultSetCount = 0;
32 enum REMIND_TIMER_ARGS : int32_t {
33 ARG_DB_PATH = 0,
34 ARG_VERSION,
35 ARG_URI,
36 ARG_SUBSCRIBER_ID,
37 ARG_BUNDLE_NAME,
38 ARG_USER_ID,
39 ARG_TIME,
40 ARGS_SIZE
41 };
RemindTimerFunc(const std::vector<std::string> & args)42 std::string RemindTimerFunc(const std::vector<std::string> &args)
43 {
44 size_t size = args.size();
45 if (size != ARGS_SIZE) {
46 ZLOGE("RemindTimerFunc args size error, %{public}zu", size);
47 return "";
48 }
49 std::string dbPath = args[ARG_DB_PATH];
50 int version = std::strtol(args[ARG_VERSION].c_str(), nullptr, 0);
51 Key key(args[ARG_URI], std::strtoll(args[ARG_SUBSCRIBER_ID].c_str(), nullptr, 0), args[ARG_BUNDLE_NAME]);
52 int64_t reminderTime = std::strtoll(args[ARG_TIME].c_str(), nullptr, 0);
53 int32_t userId = std::strtol(args[ARG_USER_ID].c_str(), nullptr, 0);
54 SchedulerManager::GetInstance().SetTimer(dbPath, userId, version, key, reminderTime);
55 return args[ARG_TIME];
56 }
57
RdbDelegate(const std::string & dir,int version,bool registerFunction,bool isEncrypt,const std::string & secretMetaKey)58 RdbDelegate::RdbDelegate(const std::string &dir, int version, bool registerFunction,
59 bool isEncrypt, const std::string &secretMetaKey)
60 {
61 RdbStoreConfig config(dir);
62 config.SetCreateNecessary(false);
63 if (isEncrypt) {
64 DistributedData::SecretKeyMetaData secretKeyMeta;
65 DistributedData::MetaDataManager::GetInstance().LoadMeta(secretMetaKey, secretKeyMeta, true);
66 std::vector<uint8_t> decryptKey;
67 DistributedData::CryptoManager::GetInstance().Decrypt(secretKeyMeta.sKey, decryptKey);
68 config.SetEncryptKey(decryptKey);
69 std::fill(decryptKey.begin(), decryptKey.end(), 0);
70 }
71 if (registerFunction) {
72 config.SetScalarFunction("remindTimer", ARGS_SIZE, RemindTimerFunc);
73 }
74 DefaultOpenCallback callback;
75 store_ = RdbHelper::GetRdbStore(config, version, callback, errCode_);
76 if (errCode_ != E_OK) {
77 ZLOGW("GetRdbStore failed, errCode is %{public}d, dir is %{public}s", errCode_,
78 DistributedData::Anonymous::Change(dir).c_str());
79 }
80 }
81
Insert(const std::string & tableName,const DataShareValuesBucket & valuesBucket)82 int64_t RdbDelegate::Insert(const std::string &tableName, const DataShareValuesBucket &valuesBucket)
83 {
84 if (store_ == nullptr) {
85 ZLOGE("store is null");
86 return 0;
87 }
88 int64_t rowId = 0;
89 ValuesBucket bucket = RdbDataShareAdapter::RdbUtils::ToValuesBucket(valuesBucket);
90 int ret = store_->Insert(rowId, tableName, bucket);
91 if (ret != E_OK) {
92 ZLOGE("Insert failed %{public}s %{public}d", tableName.c_str(), ret);
93 }
94 return rowId;
95 }
Update(const std::string & tableName,const DataSharePredicates & predicate,const DataShareValuesBucket & valuesBucket)96 int64_t RdbDelegate::Update(
97 const std::string &tableName, const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket)
98 {
99 if (store_ == nullptr) {
100 ZLOGE("store is null");
101 return 0;
102 }
103 int changeCount = 0;
104 ValuesBucket bucket = RdbDataShareAdapter::RdbUtils::ToValuesBucket(valuesBucket);
105 RdbPredicates predicates = RdbDataShareAdapter::RdbUtils::ToPredicates(predicate, tableName);
106 int ret = store_->Update(changeCount, bucket, predicates);
107 if (ret != E_OK) {
108 ZLOGE("Update failed %{public}s %{public}d", tableName.c_str(), ret);
109 }
110 return changeCount;
111 }
Delete(const std::string & tableName,const DataSharePredicates & predicate)112 int64_t RdbDelegate::Delete(const std::string &tableName, const DataSharePredicates &predicate)
113 {
114 if (store_ == nullptr) {
115 ZLOGE("store is null");
116 return 0;
117 }
118 int changeCount = 0;
119 RdbPredicates predicates = RdbDataShareAdapter::RdbUtils::ToPredicates(predicate, tableName);
120 int ret = store_->Delete(changeCount, predicates);
121 if (ret != E_OK) {
122 ZLOGE("Delete failed %{public}s %{public}d", tableName.c_str(), ret);
123 }
124 return changeCount;
125 }
Query(const std::string & tableName,const DataSharePredicates & predicates,const std::vector<std::string> & columns,int & errCode)126 std::shared_ptr<DataShareResultSet> RdbDelegate::Query(const std::string &tableName,
127 const DataSharePredicates &predicates, const std::vector<std::string> &columns, int &errCode)
128 {
129 if (store_ == nullptr) {
130 ZLOGE("store is null");
131 errCode = errCode_;
132 return nullptr;
133 }
134 int count = resultSetCount.fetch_add(1);
135 ZLOGD("start query %{public}d", count);
136 if (count > MAX_RESULTSET_COUNT) {
137 ZLOGE("resultSetCount is full");
138 resultSetCount--;
139 return nullptr;
140 }
141 RdbPredicates rdbPredicates = RdbDataShareAdapter::RdbUtils::ToPredicates(predicates, tableName);
142 std::shared_ptr<NativeRdb::ResultSet> resultSet = store_->QueryByStep(rdbPredicates, columns);
143 if (resultSet == nullptr) {
144 ZLOGE("Query failed %{public}s", tableName.c_str());
145 resultSetCount--;
146 return nullptr;
147 }
148 auto bridge = RdbDataShareAdapter::RdbUtils::ToResultSetBridge(resultSet);
149 return std::shared_ptr<DataShareResultSet>(new DataShareResultSet(bridge), [](auto p) {
150 ZLOGD("release resultset");
151 resultSetCount--;
152 delete p;
153 });
154 }
155
Query(const std::string & sql,const std::vector<std::string> & selectionArgs)156 std::string RdbDelegate::Query(const std::string &sql, const std::vector<std::string> &selectionArgs)
157 {
158 if (store_ == nullptr) {
159 ZLOGE("store is null");
160 return "";
161 }
162 auto resultSet = store_->QueryByStep(sql, selectionArgs);
163 if (resultSet == nullptr) {
164 ZLOGE("Query failed %{private}s", sql.c_str());
165 return "";
166 }
167 ResultSetJsonFormatter formatter(std::move(resultSet));
168 return DistributedData::Serializable::Marshall(formatter);
169 }
170
QuerySql(const std::string & sql)171 std::shared_ptr<NativeRdb::ResultSet> RdbDelegate::QuerySql(const std::string &sql)
172 {
173 if (store_ == nullptr) {
174 ZLOGE("store is null");
175 return nullptr;
176 }
177 return store_->QuerySql(sql);
178 }
179 } // namespace OHOS::DataShare