• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "calllog_database.h"
17 
18 #include "common.h"
19 #include "contacts_database.h"
20 #include "contacts_type.h"
21 
22 namespace OHOS {
23 namespace Contacts {
24 std::shared_ptr<CallLogDataBase> CallLogDataBase::callLogDataBase_ = nullptr;
25 std::shared_ptr<OHOS::NativeRdb::RdbStore> CallLogDataBase::store_ = nullptr;
26 
CallLogDataBase()27 CallLogDataBase::CallLogDataBase()
28 {
29     std::string g_databaseName = ContactsPath::RDB_EL1_PATH + "calls.db";
30     HILOG_INFO("CallLogDataBase g_databaseName :%{public}s", g_databaseName.c_str());
31     int errCode = OHOS::NativeRdb::E_OK;
32     OHOS::NativeRdb::RdbStoreConfig config(g_databaseName);
33     SqliteOpenHelperCallLogCallback sqliteOpenHelperCallback;
34     store_ = OHOS::NativeRdb::RdbHelper::GetRdbStore(config, DATABASE_OPEN_VERSION, sqliteOpenHelperCallback, errCode);
35     if (errCode != OHOS::NativeRdb::E_OK) {
36         HILOG_ERROR("CallLogDataBase errCode :%{public}d", errCode);
37     } else {
38         HILOG_INFO("CallLogDataBase errCode :%{public}d", errCode);
39     }
40 }
41 
GetInstance()42 std::shared_ptr<CallLogDataBase> CallLogDataBase::GetInstance()
43 {
44     if (callLogDataBase_ == nullptr) {
45         callLogDataBase_.reset(new CallLogDataBase());
46         return callLogDataBase_;
47     }
48     return callLogDataBase_;
49 }
50 
BeginTransaction()51 int CallLogDataBase::BeginTransaction()
52 {
53     if (store_ == nullptr) {
54         HILOG_ERROR("CallLogDataBase BeginTransaction store_ is nullptr");
55         return RDB_OBJECT_EMPTY;
56     }
57     int ret = store_->BeginTransaction();
58     if (ret != OHOS::NativeRdb::E_OK) {
59         HILOG_ERROR("CallLogDataBase BeginTransaction fail :%{public}d", ret);
60     }
61     return ret;
62 }
63 
Commit()64 int CallLogDataBase::Commit()
65 {
66     if (store_ == nullptr) {
67         HILOG_ERROR(" CallLogDataBase Commit store_ is nullptr");
68         return RDB_OBJECT_EMPTY;
69     }
70     int ret = store_->Commit();
71     if (ret != OHOS::NativeRdb::E_OK) {
72         HILOG_ERROR(" CallLogDataBase Commit fail :%{public}d", ret);
73     }
74     return ret;
75 }
76 
RollBack()77 int CallLogDataBase::RollBack()
78 {
79     if (store_ == nullptr) {
80         HILOG_ERROR(" CallLogDataBase RollBack store_ is nullptr");
81         return RDB_OBJECT_EMPTY;
82     }
83     int ret = store_->RollBack();
84     if (ret != OHOS::NativeRdb::E_OK) {
85         HILOG_ERROR(" CallLogDataBase RollBack fail :%{public}d", ret);
86     }
87     return ret;
88 }
89 
OnCreate(OHOS::NativeRdb::RdbStore & store)90 int SqliteOpenHelperCallLogCallback::OnCreate(OHOS::NativeRdb::RdbStore &store)
91 {
92     std::vector<int> judgeSuccess;
93     judgeSuccess.push_back(store.ExecuteSql(CREATE_VOICEMAIL));
94     judgeSuccess.push_back(store.ExecuteSql(CREATE_CALLLOG));
95     judgeSuccess.push_back(store.ExecuteSql(CREATE_REPLYING));
96     judgeSuccess.push_back(store.ExecuteSql(CREATE_DATABASE_BACKUP_TASK));
97     judgeSuccess.push_back(store.ExecuteSql(CREATE_INSERT_BACKUP_TIME));
98     judgeSuccess.push_back(store.ExecuteSql(CALL_LOG_PHONE_NUMBER_INDEX));
99     unsigned int size = judgeSuccess.size();
100     for (unsigned int i = 0; i < size; i++) {
101         if (judgeSuccess[i] != OHOS::NativeRdb::E_OK) {
102             HILOG_ERROR("SqliteOpenHelperCallLogCallback create table error : %{public}d", judgeSuccess[i]);
103         }
104     }
105     return OHOS::NativeRdb::E_OK;
106 }
107 
OnUpgrade(OHOS::NativeRdb::RdbStore & store,int oldVersion,int newVersion)108 int SqliteOpenHelperCallLogCallback::OnUpgrade(OHOS::NativeRdb::RdbStore &store, int oldVersion, int newVersion)
109 {
110     HILOG_INFO("OnUpgrade oldVersion is %{public}d , newVersion is %{public}d", oldVersion, newVersion);
111     if (oldVersion < newVersion && newVersion == DATABASE_NEW_VERSION) {
112         store.ExecuteSql("ALTER TABLE database_backup_task ADD COLUMN sync TEXT");
113     }
114     if (oldVersion < newVersion && newVersion == DATABASE_VERSION_2) {
115         UpgradeToV2(store, oldVersion, newVersion);
116     }
117     store.SetVersion(newVersion);
118     return OHOS::NativeRdb::E_OK;
119 }
120 
UpgradeToV2(OHOS::NativeRdb::RdbStore & store,int oldVersion,int newVersion)121 void SqliteOpenHelperCallLogCallback::UpgradeToV2(OHOS::NativeRdb::RdbStore &store, int oldVersion, int newVersion)
122 {
123     if (oldVersion >= newVersion || newVersion != DATABASE_VERSION_2) {
124         return;
125     }
126     store.ExecuteSql("ALTER TABLE callog ADD COLUMN features INTEGERT DEFAULT 0;");
127 }
128 
OnDowngrade(OHOS::NativeRdb::RdbStore & store,int oldVersion,int newVersion)129 int SqliteOpenHelperCallLogCallback::OnDowngrade(OHOS::NativeRdb::RdbStore &store, int oldVersion, int newVersion)
130 {
131     HILOG_INFO("OnDowngrade oldVersion is %{public}d , newVersion is %{public}d", oldVersion, newVersion);
132     if (oldVersion > newVersion && newVersion == DATABASE_OPEN_VERSION) {
133         store.ExecuteSql(
134             "CREATE TABLE IF NOT EXISTS database_backup (id INTEGER PRIMARY KEY AUTOINCREMENT, backup_time "
135             "TEXT, backup_path TEXT, remarks TEXT)");
136         store.ExecuteSql(
137             "INSERT INTO database_backup(id, backup_time, backup_path, remarks) SELECT id, "
138             "backup_time, backup_path, remarks FROM database_backup_task");
139         store.ExecuteSql("DROP table database_backup_task");
140         store.ExecuteSql("ALTER table database_backup RENAME TO database_backup_task");
141         store.ExecuteSql(CREATE_INSERT_BACKUP_TIME);
142     }
143     int ret = store.SetVersion(newVersion);
144     return ret;
145 }
146 
147 /**
148  * @brief InsertCallLog operation
149  *
150  * @param insertValues Conditions for update operation
151  *
152  * @return InsertCallLog operation results
153  */
InsertCallLog(OHOS::NativeRdb::ValuesBucket insertValues)154 int64_t CallLogDataBase::InsertCallLog(OHOS::NativeRdb::ValuesBucket insertValues)
155 {
156     int64_t outRowId = RDB_EXECUTE_FAIL;
157     if (store_ == nullptr) {
158         HILOG_ERROR("CallLogDataBase Insert store_ is  nullptr");
159         return RDB_OBJECT_EMPTY;
160     }
161     QueryContactsByInsertCalls(insertValues);
162     int ret = store_->Insert(outRowId, CallsTableName::CALLLOG, insertValues);
163     if (ret != OHOS::NativeRdb::E_OK) {
164         HILOG_ERROR("CallLogDataBase InsertCallLog ret :%{public}d", ret);
165         return RDB_EXECUTE_FAIL;
166     }
167     return outRowId;
168 }
169 
170 /**
171  * @brief UpdateCallLog operation
172  *
173  * @param values Conditions for update operation
174  * @param predicates Conditions for update operation
175  *
176  * @return UpdateCallLog operation results
177  */
UpdateCallLog(OHOS::NativeRdb::ValuesBucket values,OHOS::NativeRdb::RdbPredicates & predicates)178 int CallLogDataBase::UpdateCallLog(OHOS::NativeRdb::ValuesBucket values, OHOS::NativeRdb::RdbPredicates &predicates)
179 {
180     if (store_ == nullptr) {
181         HILOG_ERROR("CallLogDataBase Update store_ is  nullptr");
182         return RDB_OBJECT_EMPTY;
183     }
184     if (values.HasColumn(CallLogColumns::PHONE_NUMBER)) {
185         QueryContactsByInsertCalls(values);
186     }
187     int changeRow;
188     int ret = store_->Update(changeRow, values, predicates);
189     if (ret != OHOS::NativeRdb::E_OK) {
190         HILOG_ERROR("CallLogDataBase UpdateCallLog ret :%{public}d", ret);
191         return RDB_EXECUTE_FAIL;
192     }
193     return ret;
194 }
195 
196 /**
197  * @brief DeleteCallLog operation
198  *
199  * @param predicates Conditions for delete operation
200  *
201  * @return DeleteCallLog operation results
202  */
DeleteCallLog(OHOS::NativeRdb::RdbPredicates & predicates)203 int CallLogDataBase::DeleteCallLog(OHOS::NativeRdb::RdbPredicates &predicates)
204 {
205     if (store_ == nullptr) {
206         HILOG_ERROR("CallLogDataBase Delete store_ is  nullptr");
207         return RDB_OBJECT_EMPTY;
208     }
209     int deleteRow;
210     int ret = store_->Delete(deleteRow, predicates);
211     if (ret != OHOS::NativeRdb::E_OK) {
212         HILOG_ERROR("CallLogDataBase DeleteCallLog ret :%{public}d", ret);
213         return RDB_EXECUTE_FAIL;
214     }
215     return ret;
216 }
217 
218 /**
219  * @brief QueryContacts operation
220  *
221  * @param predicates Conditions for query operation
222  * @param columns Conditions for query operation
223  *
224  * @return Query database results
225  */
Query(OHOS::NativeRdb::RdbPredicates & predicates,std::vector<std::string> columns)226 std::shared_ptr<OHOS::NativeRdb::ResultSet> CallLogDataBase::Query(
227     OHOS::NativeRdb::RdbPredicates &predicates, std::vector<std::string> columns)
228 {
229     if (store_ == nullptr) {
230         HILOG_ERROR("CallLogDataBase Delete store_ is  nullptr");
231         return nullptr;
232     }
233 
234     return store_->Query(predicates, columns);
235 }
236 
237 /**
238  * @brief QueryContacts By InsertCallLog get name and phone to UpdateTopContact
239  *
240  * @param insertValues Inserted data values
241  *
242  * @return void
243  */
QueryContactsByInsertCalls(OHOS::NativeRdb::ValuesBucket & insertValues)244 void CallLogDataBase::QueryContactsByInsertCalls(OHOS::NativeRdb::ValuesBucket &insertValues)
245 {
246     if (!insertValues.HasColumn(CallLogColumns::PHONE_NUMBER)) {
247         HILOG_ERROR("QueryContactsByInsertCalls phone_number is required");
248         return;
249     }
250     OHOS::NativeRdb::ValueObject value;
251     insertValues.GetObject(CallLogColumns::PHONE_NUMBER, value);
252     std::string phoneNumber;
253     value.GetString(phoneNumber);
254     ContactsType contactsType;
255     static std::shared_ptr<ContactsDataBase> contactsDataBase = ContactsDataBase::GetInstance();
256     if (contactsDataBase == nullptr || contactsDataBase->contactStore_ == nullptr) {
257         HILOG_ERROR("ContactsDataBase is nullptr or ContactsDataBase->contactStore_ is nullptr");
258         return;
259     }
260     int typeNameId = contactsType.LookupTypeId(contactsDataBase->contactStore_, ContentTypeData::PHONE);
261     std::string sql = "SELECT display_name, contact_id FROM ";
262     sql.append(ViewName::VIEW_CONTACT_DATA)
263         .append(" WHERE raw_contact_id = ")
264         .append("(SELECT min(raw_contact_id) FROM ")
265         .append(ViewName::VIEW_CONTACT_DATA)
266         .append(" WHERE detail_info = ?")
267         .append(" AND is_deleted = 0")
268         .append(") AND type_id = ")
269         .append(std::to_string(typeNameId))
270         .append(" AND is_deleted = 0");
271     std::vector<std::string> selectionArgs;
272     selectionArgs.push_back(phoneNumber);
273     auto resultSet = contactsDataBase->contactStore_->QuerySql(sql, selectionArgs);
274     if (resultSet->GoToFirstRow() == OHOS::NativeRdb::E_OK) {
275         std::string quickSearchKey;
276         std::string name;
277         resultSet->GetString(0, name);
278         resultSet->GetString(1, quickSearchKey);
279         resultSet->GoToNextRow();
280         insertValues.Delete(CallLogColumns::DISPLAY_NAME);
281         insertValues.PutString(CallLogColumns::DISPLAY_NAME, name);
282         insertValues.Delete(CallLogColumns::QUICK_SEARCH_KEY);
283         insertValues.PutString(CallLogColumns::QUICK_SEARCH_KEY, quickSearchKey);
284     }
285     resultSet->Close();
286     int ret = UpdateTopContact(insertValues);
287     if (ret != OHOS::NativeRdb::E_OK) {
288         HILOG_ERROR("QueryContactsByInsertCalls UpdateTopContact is error");
289     }
290 }
291 
292 /**
293  * @brief Update the callLog contact frequency and contact time
294  *
295  * @param insertValues Get contact time
296  * @param phoneNumber phoneNumber To select callLog
297  *
298  * @return update frequency and time result code
299  */
UpdateTopContact(OHOS::NativeRdb::ValuesBucket & insertValues)300 int CallLogDataBase::UpdateTopContact(OHOS::NativeRdb::ValuesBucket &insertValues)
301 {
302     if (!insertValues.HasColumn(CallLogColumns::BEGIN_TIME)) {
303         return RDB_EXECUTE_FAIL;
304     }
305     OHOS::NativeRdb::ValueObject value;
306     insertValues.GetObject(CallLogColumns::BEGIN_TIME, value);
307     int contactedTime;
308     value.GetInt(contactedTime);
309     std::string sqlBuild = "UPDATE ";
310     sqlBuild.append(ContactTableName::RAW_CONTACT)
311         .append(" SET lastest_contacted_time = ")
312         .append(std::to_string(contactedTime))
313         .append(", contacted_count = (contacted_count + 1) ")
314         .append(" WHERE contact_id = ")
315         .append("(SELECT DISTINCT min(contact_id) FROM ")
316         .append(ViewName::VIEW_CONTACT_DATA)
317         .append(" WHERE detail_info = ? ")
318         .append(")");
319     std::vector<OHOS::NativeRdb::ValueObject> bindArgs;
320     OHOS::NativeRdb::ValueObject phone;
321     insertValues.GetObject(CallLogColumns::PHONE_NUMBER, phone);
322     bindArgs.push_back(phone);
323     int ret = ContactsDataBase::GetInstance()->contactStore_->ExecuteSql(sqlBuild, bindArgs);
324     if (ret != OHOS::NativeRdb::E_OK) {
325         HILOG_ERROR("store ExecuteSql error");
326         return RDB_EXECUTE_FAIL;
327     }
328     return RDB_EXECUTE_OK;
329 }
330 } // namespace Contacts
331 } // namespace OHOS