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