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 #define MLOG_TAG "RdbStore"
17
18 #include "ringtone_rdbstore.h"
19
20 #include <sys/stat.h>
21
22 #include "rdb_sql_utils.h"
23 #include "ringtone_errno.h"
24 #include "ringtone_log.h"
25 #include "ringtone_tracer.h"
26 #include "ringtone_utils.h"
27 #include "result_set_utils.h"
28 #include "ringtone_rdb_callbacks.h"
29 #include "dfx_const.h"
30 #include "preferences_helper.h"
31
32 namespace OHOS::Media {
33 using namespace std;
34 using namespace OHOS;
35
36 const int CONTEXT_AREA_EL1 = 0;
37 const int CONTEXT_AREA_EL2 = 1;
38 const int RDB_AREA_EL1 = 0;
39
40 shared_ptr<NativeRdb::RdbStore> RingtoneRdbStore::rdbStore_;
41
GetInstance(const std::shared_ptr<OHOS::AbilityRuntime::Context> & context)42 shared_ptr<RingtoneUnistore> RingtoneRdbStore::GetInstance(
43 const std::shared_ptr<OHOS::AbilityRuntime::Context> &context)
44 {
45 static shared_ptr<RingtoneRdbStore> instance = nullptr;
46 if (instance == nullptr && context == nullptr) {
47 RINGTONE_ERR_LOG("RingtoneRdbStore is not initialized");
48 return nullptr;
49 }
50 if (instance == nullptr) {
51 instance = make_shared<RingtoneRdbStore>(context);
52 if (instance->Init() != 0) {
53 RINGTONE_ERR_LOG("init RingtoneRdbStore failed");
54 instance = nullptr;
55 return instance;
56 }
57 }
58 return instance;
59 }
60
RingtoneRdbStore(const shared_ptr<OHOS::AbilityRuntime::Context> & context)61 RingtoneRdbStore::RingtoneRdbStore(const shared_ptr<OHOS::AbilityRuntime::Context> &context)
62 {
63 if (context == nullptr) {
64 RINGTONE_ERR_LOG("Failed to get context");
65 return;
66 }
67
68 auto preArea = context->GetArea();
69 context->SwitchArea(CONTEXT_AREA_EL1);
70 context->GetPreferencesDir();
71
72 context->SwitchArea(CONTEXT_AREA_EL2);
73 context->GetFilesDir();
74
75 context->SwitchArea(preArea);
76
77 string databaseDir = RINGTONE_LIBRARY_DB_PATH_EL1;
78 string name = RINGTONE_LIBRARY_DB_NAME;
79 int32_t errCode = 0;
80 string realPath = NativeRdb::RdbSqlUtils::GetDefaultDatabasePath(databaseDir, name, errCode);
81 config_.SetName(move(name));
82 config_.SetPath(move(realPath));
83 config_.SetBundleName(context->GetBundleName());
84 config_.SetArea(RDB_AREA_EL1);
85 config_.SetSecurityLevel(NativeRdb::SecurityLevel::S3);
86 }
87
Init()88 int32_t RingtoneRdbStore::Init()
89 {
90 auto ret = RingtoneUtils::ChecMoveDb();
91 if (ret == E_ERR) {
92 RINGTONE_ERR_LOG("check is failed");
93 return E_ERR;
94 }
95 RINGTONE_INFO_LOG("Init rdb store");
96 if (rdbStore_ != nullptr) {
97 return E_OK;
98 }
99
100 int32_t errCode = 0;
101 RingtoneDataCallBack rdbDataCallBack;
102 rdbStore_ = NativeRdb::RdbHelper::GetRdbStore(config_, RINGTONE_RDB_VERSION, rdbDataCallBack, errCode);
103 if (rdbStore_ == nullptr) {
104 RINGTONE_ERR_LOG("GetRdbStore is failed , errCode=%{public}d", errCode);
105 return E_ERR;
106 }
107 RINGTONE_INFO_LOG("SUCCESS");
108 return E_OK;
109 }
110
111 RingtoneRdbStore::~RingtoneRdbStore() = default;
112
Stop()113 void RingtoneRdbStore::Stop()
114 {
115 if (rdbStore_ == nullptr) {
116 return;
117 }
118
119 rdbStore_ = nullptr;
120 }
121
Insert(RingtoneDataCommand & cmd,int64_t & rowId)122 int32_t RingtoneRdbStore::Insert(RingtoneDataCommand &cmd, int64_t &rowId)
123 {
124 RingtoneTracer tracer;
125 tracer.Start("RingtoneRdbStore::Insert");
126 if (rdbStore_ == nullptr) {
127 RINGTONE_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
128 return E_HAS_DB_ERROR;
129 }
130
131 int32_t ret = rdbStore_->Insert(rowId, cmd.GetTableName(), cmd.GetValueBucket());
132 if (ret != NativeRdb::E_OK) {
133 RINGTONE_ERR_LOG("rdbStore_->Insert failed, ret = %{public}d", ret);
134 return E_HAS_DB_ERROR;
135 }
136
137 RINGTONE_DEBUG_LOG("rdbStore_->Insert end, rowId = %d, ret = %{public}d", (int)rowId, ret);
138 return ret;
139 }
140
Delete(RingtoneDataCommand & cmd,int32_t & deletedRows)141 int32_t RingtoneRdbStore::Delete(RingtoneDataCommand &cmd, int32_t &deletedRows)
142 {
143 if (rdbStore_ == nullptr) {
144 RINGTONE_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
145 return E_HAS_DB_ERROR;
146 }
147 RingtoneTracer tracer;
148 tracer.Start("RdbStore->DeleteByCmd");
149
150 auto predicates = cmd.GetAbsRdbPredicates();
151 RINGTONE_INFO_LOG("delete WhereClause=%{public}s", predicates->GetWhereClause().c_str());
152 for (const auto &arg : predicates->GetWhereArgs()) {
153 RINGTONE_INFO_LOG("delete arg=%{private}s", arg.c_str());
154 }
155 int32_t ret = rdbStore_->Delete(deletedRows, cmd.GetTableName(), predicates->GetWhereClause(),
156 predicates->GetWhereArgs());
157 if (ret != NativeRdb::E_OK) {
158 RINGTONE_ERR_LOG("rdbStore_->Delete failed, ret = %{public}d", ret);
159 return E_HAS_DB_ERROR;
160 }
161 RINGTONE_INFO_LOG("Delete end, rows = %{public}d", deletedRows);
162 return ret;
163 }
164
Update(RingtoneDataCommand & cmd,int32_t & changedRows)165 int32_t RingtoneRdbStore::Update(RingtoneDataCommand &cmd, int32_t &changedRows)
166 {
167 if (rdbStore_ == nullptr) {
168 RINGTONE_ERR_LOG("rdbStore_ is nullptr");
169 return E_HAS_DB_ERROR;
170 }
171
172 RingtoneTracer tracer;
173 tracer.Start("RdbStore->UpdateByCmd");
174 RINGTONE_INFO_LOG("update WhereClause=%{public}s", cmd.GetAbsRdbPredicates()->GetWhereClause().c_str());
175 for (const auto &arg : cmd.GetAbsRdbPredicates()->GetWhereArgs()) {
176 RINGTONE_INFO_LOG("update arg=%{private}s", arg.c_str());
177 }
178 int32_t ret = rdbStore_->Update(changedRows, cmd.GetTableName(), cmd.GetValueBucket(),
179 cmd.GetAbsRdbPredicates()->GetWhereClause(), cmd.GetAbsRdbPredicates()->GetWhereArgs());
180 if (ret != NativeRdb::E_OK) {
181 RINGTONE_ERR_LOG("rdbStore_->Update failed, ret = %{public}d", ret);
182 return E_HAS_DB_ERROR;
183 }
184 RINGTONE_INFO_LOG("Update end, rows = %{public}d", changedRows);
185 return ret;
186 }
187
Query(RingtoneDataCommand & cmd,const vector<string> & columns)188 shared_ptr<NativeRdb::ResultSet> RingtoneRdbStore::Query(RingtoneDataCommand &cmd,
189 const vector<string> &columns)
190 {
191 if (rdbStore_ == nullptr) {
192 RINGTONE_ERR_LOG("rdbStore_ is nullptr");
193 return nullptr;
194 }
195
196 RingtoneTracer tracer;
197 tracer.Start("RdbStore->QueryByCmd");
198
199 auto resultSet = rdbStore_->Query(*cmd.GetAbsRdbPredicates(), columns);
200 return resultSet;
201 }
202
ExecuteSql(const string & sql)203 int32_t RingtoneRdbStore::ExecuteSql(const string &sql)
204 {
205 if (rdbStore_ == nullptr) {
206 RINGTONE_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
207 return E_HAS_DB_ERROR;
208 }
209 RingtoneTracer tracer;
210 tracer.Start("RdbStore->ExecuteSql");
211 int32_t ret = rdbStore_->ExecuteSql(sql);
212 if (ret != NativeRdb::E_OK) {
213 RINGTONE_ERR_LOG("rdbStore_->ExecuteSql failed, ret = %{public}d", ret);
214 return E_HAS_DB_ERROR;
215 }
216 return ret;
217 }
218
QuerySql(const string & sql,const vector<string> & selectionArgs)219 shared_ptr<NativeRdb::ResultSet> RingtoneRdbStore::QuerySql(const string &sql, const vector<string> &selectionArgs)
220 {
221 if (rdbStore_ == nullptr) {
222 RINGTONE_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
223 return nullptr;
224 }
225
226 RingtoneTracer tracer;
227 tracer.Start("RdbStore->QuerySql");
228 auto resultSet = rdbStore_->QuerySql(sql, selectionArgs);
229 return resultSet;
230 }
231
GetRaw()232 shared_ptr<NativeRdb::RdbStore> RingtoneRdbStore::GetRaw()
233 {
234 return rdbStore_;
235 }
236 } // namespace OHOS::Media
237