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