• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #include "c_request_database.h"
17 
18 #include <securec.h>
19 
20 #include <algorithm>
21 #include <cstdint>
22 #include <iostream>
23 #include <string>
24 #include <vector>
25 
26 #include "base/request/request/common/include/log.h"
27 #include "c_task_info.h"
28 #include "cxx.h"
29 #include "errors.h"
30 #include "log.h"
31 #include "manage/database.rs.h"
32 #include "manage/network.rs.h"
33 #include "manage/query.rs.h"
34 #include "rdb_errno.h"
35 #include "task/config.rs.h"
36 #include "task/info.rs.h"
37 #include "task/reason.rs.h"
38 namespace OHOS::Request {
39 
BuildDatabase(std::string path,bool encryptStatus,std::shared_ptr<OHOS::NativeRdb::RdbStore> & store)40 void BuildDatabase(std::string path, bool encryptStatus, std::shared_ptr<OHOS::NativeRdb::RdbStore> &store)
41 {
42     int errCode = OHOS::NativeRdb::E_OK;
43     OHOS::NativeRdb::RdbStoreConfig config(path);
44     if (encryptStatus) {
45         config.SetSecurityLevel(NativeRdb::SecurityLevel::S1);
46         config.SetEncryptStatus(true);
47     }
48     RequestDBOpenCallback requestDBOpenCallback;
49     // retry 10 times
50     for (int index = 0; index < 10; ++index) {
51         store = OHOS::NativeRdb::RdbHelper::GetRdbStore(config, DATABASE_VERSION, requestDBOpenCallback, errCode);
52         if (store == nullptr) {
53             REQUEST_HILOGE("GetRdbStore failed: %{public}d, try DeleteRdbStore", errCode);
54             OHOS::NativeRdb::RdbHelper::DeleteRdbStore(path);
55         } else {
56             REQUEST_HILOGI("End get request database successful");
57             return;
58         }
59     }
60 }
61 
RequestDataBase(std::string path,bool encryptStatus)62 RequestDataBase::RequestDataBase(std::string path, bool encryptStatus)
63 {
64     REQUEST_HILOGI("Process Get request database");
65     BuildDatabase(path, encryptStatus, store_);
66 }
67 
CheckAndRebuildDataBase(int errCode)68 void RequestDataBase::CheckAndRebuildDataBase(int errCode)
69 {
70     if (errCode == OHOS::NativeRdb::E_SQLITE_CORRUPT) {
71         REQUEST_HILOGE("Database corruption : %{public}d", errCode);
72         int errCode = OHOS::NativeRdb::RdbHelper::DeleteRdbStore(OHOS::Request::DB_NAME);
73         if (errCode != OHOS::NativeRdb::E_OK) {
74             REQUEST_HILOGE("delete database failed: %{public}d", errCode);
75             return;
76         }
77         BuildDatabase(OHOS::Request::DB_NAME, true, store_);
78     }
79 }
80 
GetInstance(std::string path,bool encryptStatus)81 RequestDataBase &RequestDataBase::GetInstance(std::string path, bool encryptStatus)
82 {
83     static RequestDataBase requestDataBase(path, encryptStatus);
84     return requestDataBase;
85 }
86 
Insert(const std::string & table,const OHOS::NativeRdb::ValuesBucket & insertValues)87 bool RequestDataBase::Insert(const std::string &table, const OHOS::NativeRdb::ValuesBucket &insertValues)
88 {
89     if (store_ == nullptr) {
90         return false;
91     }
92 
93     int64_t outRowId = 0;
94     int ret = store_->Insert(outRowId, table, insertValues);
95     REQUEST_HILOGD("Request databases insert values, ret: %{public}d", ret);
96     CheckAndRebuildDataBase(ret);
97     return ret == OHOS::NativeRdb::E_OK;
98 }
99 
Update(const OHOS::NativeRdb::ValuesBucket values,const OHOS::NativeRdb::AbsRdbPredicates & predicates)100 bool RequestDataBase::Update(
101     const OHOS::NativeRdb::ValuesBucket values, const OHOS::NativeRdb::AbsRdbPredicates &predicates)
102 {
103     if (store_ == nullptr) {
104         return false;
105     }
106 
107     int changedRows = 0;
108     int ret = store_->Update(changedRows, values, predicates);
109     REQUEST_HILOGD("Request databases update, changedRows: %{public}d, ret: %{public}d", changedRows, ret);
110     CheckAndRebuildDataBase(ret);
111     return ret == OHOS::NativeRdb::E_OK;
112 }
113 
Query(const OHOS::NativeRdb::AbsRdbPredicates & predicates,const std::vector<std::string> & columns)114 std::shared_ptr<OHOS::NativeRdb::ResultSet> RequestDataBase::Query(
115     const OHOS::NativeRdb::AbsRdbPredicates &predicates, const std::vector<std::string> &columns)
116 {
117     if (store_ == nullptr) {
118         return nullptr;
119     }
120     return store_->QueryByStep(predicates, columns);
121 }
122 
ExecuteSql(rust::str sql)123 int RequestDataBase::ExecuteSql(rust::str sql)
124 {
125     if (store_ == nullptr) {
126         return -1;
127     }
128     int ret = store_->ExecuteSql(std::string(sql));
129     CheckAndRebuildDataBase(ret);
130     return ret;
131 }
132 
QueryInteger(rust::str sql,rust::vec<rust::i64> & res)133 int RequestDataBase::QueryInteger(rust::str sql, rust::vec<rust::i64> &res)
134 {
135     if (store_ == nullptr) {
136         return -1;
137     }
138     auto queryRet = store_->QueryByStep(std::string(sql));
139     if (queryRet == nullptr) {
140         REQUEST_HILOGE("Search failed with reason: result set is nullptr");
141         return -1;
142     }
143     int rowCount = 0;
144 
145     int errCode = queryRet->GetRowCount(rowCount);
146     if (errCode != OHOS::NativeRdb::E_OK) {
147         REQUEST_HILOGE("GetRowCount failed: %{public}d", errCode);
148         CheckAndRebuildDataBase(errCode);
149         return -1;
150     }
151     for (int i = 0; i < rowCount; i++) {
152         auto code = queryRet->GoToRow(i);
153         if (code != OHOS::NativeRdb::E_OK) {
154             REQUEST_HILOGE("result set go to %{public}d row failed %{public}d", i, code);
155             return -1;
156         }
157         int64_t value = 0;
158         queryRet->GetLong(0, value);
159         res.push_back(rust::i64(value));
160     }
161     return 0;
162 }
163 
QueryText(rust::str sql,rust::vec<rust::String> & res)164 int RequestDataBase::QueryText(rust::str sql, rust::vec<rust::String> &res)
165 {
166     if (store_ == nullptr) {
167         return -1;
168     }
169     auto queryRet = store_->QuerySql(std::string(sql));
170     if (queryRet == nullptr) {
171         REQUEST_HILOGE("Search failed with reason: result set is nullptr");
172         return -1;
173     }
174     int rowCount = 0;
175 
176     int errCode = queryRet->GetRowCount(rowCount);
177     if (errCode != OHOS::NativeRdb::E_OK) {
178         REQUEST_HILOGE("GetRowCount failed: %{public}d", errCode);
179         CheckAndRebuildDataBase(errCode);
180         return -1;
181     }
182     for (int i = 0; i < rowCount; i++) {
183         if (queryRet->GoToRow(i) != OHOS::NativeRdb::E_OK) {
184             REQUEST_HILOGE("result set go to %{public}d row failed", i);
185             return -1;
186         }
187         std::string value = "";
188         queryRet->GetString(i, value);
189         res.push_back(rust::string(value));
190     }
191     return 0;
192 }
193 
Delete(const OHOS::NativeRdb::AbsRdbPredicates & predicates)194 bool RequestDataBase::Delete(const OHOS::NativeRdb::AbsRdbPredicates &predicates)
195 {
196     if (store_ == nullptr) {
197         return false;
198     }
199 
200     int deletedRows = 0;
201     int ret = store_->Delete(deletedRows, predicates);
202     REQUEST_HILOGD("Request databases delete rows, rows: %{public}d, ret: %{public}d", ret, deletedRows);
203     CheckAndRebuildDataBase(ret);
204     return ret == OHOS::NativeRdb::E_OK;
205 }
206 
GetAppTaskQosInfos(rust::str sql,rust::vec<TaskQosInfo> & res)207 int RequestDataBase::GetAppTaskQosInfos(rust::str sql, rust::vec<TaskQosInfo> &res)
208 {
209     if (store_ == nullptr) {
210         return -1;
211     }
212     auto queryRet = store_->QueryByStep(std::string(sql));
213     int rowCount = 0;
214 
215     if (queryRet == nullptr) {
216         REQUEST_HILOGE("GetRunningTasksArray result set is nullptr");
217         return -1;
218     }
219 
220     int errCode = queryRet->GetRowCount(rowCount);
221     if (errCode != OHOS::NativeRdb::E_OK) {
222         REQUEST_HILOGE("GetRowCount failed: %{public}d", errCode);
223         CheckAndRebuildDataBase(errCode);
224         return -1;
225     }
226 
227     if (rowCount == 0) {
228         return -1;
229     }
230 
231     for (auto i = 0; i < rowCount; i++) {
232         if (queryRet->GoToRow(i) != OHOS::NativeRdb::E_OK) {
233             REQUEST_HILOGE("GetRunningTasksArray result set go to %{public}d row failed", i);
234             return -1;
235         }
236         int taskId, action, mode, state, priority;
237         queryRet->GetInt(0, taskId);   // Line 0 is 'task_id'
238         queryRet->GetInt(1, action);   // Line 1 is 'action'
239         queryRet->GetInt(2, mode);     // Line 2 is 'mode'
240         queryRet->GetInt(3, state);    // Line 3 is 'state'
241         queryRet->GetInt(4, priority); // Line 4 is 'priority'
242         res.push_back(TaskQosInfo{ taskId, action, mode, state, priority });
243     }
244     return 0;
245 }
246 
GetTaskQosInfo(rust::str sql,TaskQosInfo & res)247 int RequestDataBase::GetTaskQosInfo(rust::str sql, TaskQosInfo &res)
248 {
249     if (store_ == nullptr) {
250         return -1;
251     }
252     auto queryRet = store_->QueryByStep(std::string(sql));
253     int rowCount = 0;
254 
255     if (queryRet == nullptr) {
256         REQUEST_HILOGE("GetTaskQosInfo result set is nullptr");
257         return -1;
258     }
259 
260     int errCode = queryRet->GetRowCount(rowCount);
261     if (errCode != OHOS::NativeRdb::E_OK) {
262         REQUEST_HILOGE("GetRowCount failed: %{public}d", errCode);
263         CheckAndRebuildDataBase(errCode);
264         return -1;
265     }
266 
267     if (rowCount == 0) {
268         return -1;
269     }
270 
271     if (queryRet->GoToRow(0) != OHOS::NativeRdb::E_OK) {
272         REQUEST_HILOGE("GetTaskQosInfo result set go to 0 row failed");
273         return -1;
274     }
275     int64_t action, mode, state, priority;
276     queryRet->GetLong(0, action);   // Line 0 is 'action'
277     queryRet->GetLong(1, mode);     // Line 1 is 'mode'
278     queryRet->GetLong(2, state);    // Line 2 is 'state'
279     queryRet->GetLong(3, priority); // Line 3 is 'priority'
280     res.action = static_cast<uint8_t>(action);
281     res.mode = static_cast<uint8_t>(mode);
282     res.state = static_cast<uint8_t>(state);
283     res.priority = static_cast<uint32_t>(priority);
284     return 0;
285 }
286 
OnCreate(OHOS::NativeRdb::RdbStore & store)287 int RequestDBOpenCallback::OnCreate(OHOS::NativeRdb::RdbStore &store)
288 {
289     return OHOS::NativeRdb::E_OK;
290 }
291 
RequestDBInitVersionTable(OHOS::NativeRdb::RdbStore & store)292 int RequestDBInitVersionTable(OHOS::NativeRdb::RdbStore &store)
293 {
294     REQUEST_HILOGD("Inits version_table");
295     // Clears `request_version` table first.
296     int ret = store.ExecuteSql("DELETE FROM request_version");
297     if (ret != OHOS::NativeRdb::E_OK) {
298         REQUEST_HILOGE("Clears request_version table failed: %{public}d", ret);
299         return ret;
300     }
301 
302     int64_t outRowId = 0;
303     OHOS::NativeRdb::ValuesBucket insertValues;
304     insertValues.PutString("version", std::string(REQUEST_DATABASE_VERSION));
305     insertValues.PutString("task_table", std::string(REQUEST_TASK_TABLE_NAME));
306     ret = store.Insert(outRowId, std::string("request_version"), insertValues);
307     if (ret != OHOS::NativeRdb::E_OK) {
308         REQUEST_HILOGE("Inits request_version table failed: %{public}d", ret);
309         return ret;
310     }
311     REQUEST_HILOGD("Inits version_table success");
312     return ret;
313 }
314 
RequestDBDropTable(OHOS::NativeRdb::RdbStore & store,const char * name)315 int RequestDBDropTable(OHOS::NativeRdb::RdbStore &store, const char *name)
316 {
317     return store.ExecuteSql(std::string("DROP TABLE IF EXISTS ") + name);
318 }
319 
RequestDBRemoveOldTables(OHOS::NativeRdb::RdbStore & store)320 void RequestDBRemoveOldTables(OHOS::NativeRdb::RdbStore &store)
321 {
322     REQUEST_HILOGD("Begins removing old tables");
323 
324     // These two tables followed was defined in 4.0-release.
325     if (RequestDBDropTable(store, "request_task_info") != OHOS::NativeRdb::E_OK) {
326         REQUEST_HILOGE("Removes request_task_info table failed");
327     }
328 
329     if (RequestDBDropTable(store, "task_info_attachment") != OHOS::NativeRdb::E_OK) {
330         REQUEST_HILOGE("Removes task_info_attachment table failed");
331     }
332 
333     // These four tables followed was defined in 4.1-beta.
334     if (RequestDBDropTable(store, "request_task_config") != OHOS::NativeRdb::E_OK) {
335         REQUEST_HILOGE("Removes request_task_config table failed");
336     }
337 
338     if (RequestDBDropTable(store, "task_config_attachment") != OHOS::NativeRdb::E_OK) {
339         REQUEST_HILOGE("Removes task_config_attachment table failed");
340     }
341 
342     if (RequestDBDropTable(store, "priority_table") != OHOS::NativeRdb::E_OK) {
343         REQUEST_HILOGE("Removes priority_table table failed");
344     }
345 
346     if (RequestDBDropTable(store, "certs_table") != OHOS::NativeRdb::E_OK) {
347         REQUEST_HILOGE("Removes certs_table table failed");
348     }
349 
350     REQUEST_HILOGD("Removes old tables end");
351 }
352 
RequestDBCheckVersion(OHOS::NativeRdb::RdbStore & store)353 int RequestDBCheckVersion(OHOS::NativeRdb::RdbStore &store)
354 {
355     REQUEST_HILOGD("RequestDBCheckVersion in");
356     auto existsRequestVersion = store.QuerySql(CHECK_REQUEST_VERSION);
357     if (existsRequestVersion == nullptr) {
358         return CHECK_VERSION_FAILED;
359     }
360     int rowCount = 0;
361     int ret = existsRequestVersion->GetRowCount(rowCount);
362     if (ret != OHOS::NativeRdb::E_OK || rowCount > 1) {
363         REQUEST_HILOGE("Gets rowCount failed, GetRowCount ret: %{public}d, rowCount: %{public}d", ret, rowCount);
364         return CHECK_VERSION_FAILED;
365     }
366 
367     if (rowCount == 0) {
368         return WITHOUT_VERSION_TABLE;
369     }
370 
371     OHOS::NativeRdb::RdbPredicates rdbPredicates("request_version");
372     auto resultSet = store.QueryByStep(rdbPredicates, { "version", "task_table" });
373     if (resultSet == nullptr) {
374         return CHECK_VERSION_FAILED;
375     }
376 
377     ret = resultSet->GetRowCount(rowCount);
378     if (ret != OHOS::NativeRdb::E_OK) {
379         REQUEST_HILOGE("Gets rowCount failed, GetRowCount ret: %{public}d", ret);
380         return CHECK_VERSION_FAILED;
381     }
382 
383     if (rowCount == 0 || rowCount > 1) {
384         return INVALID_VERSION;
385     }
386 
387     ret = resultSet->GoToRow(0);
388     if (ret != OHOS::NativeRdb::E_OK) {
389         REQUEST_HILOGE("ResultSet goes to first row failed, GoToRow ret: %{public}d", ret);
390         return CHECK_VERSION_FAILED;
391     }
392 
393     std::string version = "";
394     ret = resultSet->GetString(0, version);
395     if (ret != OHOS::NativeRdb::E_OK) {
396         REQUEST_HILOGE("ResultSet gets version failed, GetString ret: %{public}d", ret);
397         return CHECK_VERSION_FAILED;
398     }
399 
400     REQUEST_HILOGI("request database version: %{public}s", version.c_str());
401 
402     if (version == REQUEST_DATABASE_VERSION_4_1_RELEASE) {
403         return API11_4_1_RELEASE;
404     }
405     if (version == REQUEST_DATABASE_VERSION) {
406         return API12_5_0_RELEASE;
407     }
408 
409     return INVALID_VERSION;
410 }
411 
RequestDBCreateTables(OHOS::NativeRdb::RdbStore & store)412 int RequestDBCreateTables(OHOS::NativeRdb::RdbStore &store)
413 {
414     // Creates request_version table first.
415     int ret = store.ExecuteSql(CREATE_REQUEST_VERSION_TABLE);
416     if (ret != OHOS::NativeRdb::E_OK) {
417         REQUEST_HILOGE("Creates request_version table failed, ret: %{public}d", ret);
418         return ret;
419     }
420     REQUEST_HILOGI("Creates request_version table success");
421 
422     // ..then creates request_task table.
423     ret = store.ExecuteSql(CREATE_REQUEST_TASK_TABLE);
424     if (ret != OHOS::NativeRdb::E_OK) {
425         REQUEST_HILOGE("Creates request_task table failed, ret: %{public}d", ret);
426         return ret;
427     }
428     REQUEST_HILOGI("Creates request_task table success");
429     return ret;
430 }
431 
432 // Keeps this function for possible extensions later
RequestDBUpgradeFrom41(OHOS::NativeRdb::RdbStore & store)433 int RequestDBUpgradeFrom41(OHOS::NativeRdb::RdbStore &store)
434 {
435     int ret = store.ExecuteSql(REQUEST_TASK_TABLE_ADD_PROXY);
436     if (ret != OHOS::NativeRdb::E_OK && ret != OHOS::NativeRdb::E_SQLITE_ERROR) {
437         REQUEST_HILOGE("add column proxy failed, ret: %{public}d", ret);
438         return ret;
439     }
440 
441     ret = store.ExecuteSql(REQUEST_TASK_TABLE_ADD_CERTIFICATE_PINS);
442     if (ret != OHOS::NativeRdb::E_OK && ret != OHOS::NativeRdb::E_SQLITE_ERROR) {
443         REQUEST_HILOGE("add column certificate_pins failed, ret: %{public}d", ret);
444         return ret;
445     }
446 
447     ret = store.ExecuteSql(OHOS::Request::REQUEST_TASK_TABLE_ADD_BUNDLE_TYPE);
448     if (ret != OHOS::NativeRdb::E_OK && ret != OHOS::NativeRdb::E_SQLITE_ERROR) {
449         REQUEST_HILOGE("add column bundle_type failed, ret: %{public}d", ret);
450         return ret;
451     }
452 
453     ret = store.ExecuteSql(REQUEST_TASK_TABLE_ADD_ATOMIC_ACCOUNT);
454     if (ret != OHOS::NativeRdb::E_OK && ret != OHOS::NativeRdb::E_SQLITE_ERROR) {
455         REQUEST_HILOGE("add column atomic_account failed, ret: %{public}d", ret);
456         return ret;
457     }
458 
459     ret = store.ExecuteSql(REQUEST_TASK_TABLE_ADD_UID_INDEX);
460     if (ret != OHOS::NativeRdb::E_OK && ret != OHOS::NativeRdb::E_SQLITE_ERROR) {
461         REQUEST_HILOGE("add uid index failed, ret: %{public}d", ret);
462         return ret;
463     }
464     return ret;
465 }
466 
467 // This function is used to adapt beta version, remove it later.
RequestDBUpgradeFrom50(OHOS::NativeRdb::RdbStore & store)468 void RequestDBUpgradeFrom50(OHOS::NativeRdb::RdbStore &store)
469 {
470     // Ignores these error if these columns already exists.
471     store.ExecuteSql(REQUEST_TASK_TABLE_ADD_PROXY);
472     store.ExecuteSql(REQUEST_TASK_TABLE_ADD_CERTIFICATE_PINS);
473     store.ExecuteSql(REQUEST_TASK_TABLE_ADD_BUNDLE_TYPE);
474     store.ExecuteSql(REQUEST_TASK_TABLE_ADD_ATOMIC_ACCOUNT);
475     store.ExecuteSql(REQUEST_TASK_TABLE_ADD_UID_INDEX);
476 }
477 
RequestDBUpgrade(OHOS::NativeRdb::RdbStore & store)478 int RequestDBUpgrade(OHOS::NativeRdb::RdbStore &store)
479 {
480     REQUEST_HILOGD("Begins upgrading database");
481 
482     int res;
483     int version = RequestDBCheckVersion(store);
484     switch (version) {
485         case INVALID_VERSION: {
486             REQUEST_HILOGI("Upgrading database from invaliad version");
487             RequestDBRemoveOldTables(store);
488         }
489             [[fallthrough]];
490         case WITHOUT_VERSION_TABLE: {
491             REQUEST_HILOGI("Upgrading database from 4.0 or earlier");
492             res = RequestDBCreateTables(store);
493             if (res != OHOS::NativeRdb::E_OK) {
494                 return res;
495             }
496         }
497             [[fallthrough]];
498         case API11_4_1_RELEASE: {
499             REQUEST_HILOGI("Upgrading database from 4.1-Release");
500             res = RequestDBUpgradeFrom41(store);
501             if (res != OHOS::NativeRdb::E_OK) {
502                 return res;
503             }
504         }
505             [[fallthrough]];
506         case API12_5_0_RELEASE: {
507             REQUEST_HILOGI("Version is 5.0-release, no need to update database.");
508             RequestDBUpgradeFrom50(store);
509             break;
510         }
511         default: {
512             REQUEST_HILOGI("Checks version failed, cannot update request database.");
513             return OHOS::NativeRdb::E_ERROR;
514         }
515     }
516     if (version != API12_5_0_RELEASE) {
517         return RequestDBInitVersionTable(store);
518     }
519     return 0;
520 }
521 
RequestDBUpdateInvalidRecords(OHOS::NativeRdb::RdbStore & store)522 void RequestDBUpdateInvalidRecords(OHOS::NativeRdb::RdbStore &store)
523 {
524     REQUEST_HILOGI("Updates all invalid task to failed");
525 
526     OHOS::NativeRdb::ValuesBucket values;
527     values.PutInt("state", static_cast<uint8_t>(State::Failed));
528 
529     // Tasks in `WAITING` and `PAUSED` states need to be resumed,
530     // so they are not processed.
531     int changedRows = 0;
532     const uint8_t oldCreated = 0x60;
533     OHOS::NativeRdb::RdbPredicates rdbPredicates("request_task");
534     rdbPredicates.EqualTo("state", static_cast<uint8_t>(State::Running))
535         ->Or()
536         ->EqualTo("state", static_cast<uint8_t>(State::Retrying))
537         ->Or()
538         ->EqualTo("state", oldCreated);
539 
540     if (store.Update(changedRows, values, rdbPredicates) != OHOS::NativeRdb::E_OK) {
541         REQUEST_HILOGE("Updates all invalid task to `FAILED` state failed");
542         return;
543     }
544     REQUEST_HILOGI("Updates all invalid task to `FAILED` state success");
545     return;
546 }
547 
OnOpen(OHOS::NativeRdb::RdbStore & store)548 int RequestDBOpenCallback::OnOpen(OHOS::NativeRdb::RdbStore &store)
549 {
550     int ret = RequestDBUpgrade(store);
551     if (ret != 0) {
552         REQUEST_HILOGE("database upgrade failed: %{public}d", ret);
553     }
554     RequestDBUpdateInvalidRecords(store);
555     return ret;
556 }
557 
OnUpgrade(OHOS::NativeRdb::RdbStore & store,int oldVersion,int newVersion)558 int RequestDBOpenCallback::OnUpgrade(OHOS::NativeRdb::RdbStore &store, int oldVersion, int newVersion)
559 {
560     return OHOS::NativeRdb::E_OK;
561 }
562 
OnDowngrade(OHOS::NativeRdb::RdbStore & store,int oldVersion,int newVersion)563 int RequestDBOpenCallback::OnDowngrade(OHOS::NativeRdb::RdbStore &store, int oldVersion, int newVersion)
564 {
565     return OHOS::NativeRdb::E_OK;
566 }
567 } // namespace OHOS::Request
568 
569 namespace {
CFormItemToBlob(const CFormItem * cpointer,uint32_t length)570 std::vector<uint8_t> CFormItemToBlob(const CFormItem *cpointer, uint32_t length)
571 {
572     std::vector<uint8_t> blob;
573     for (uint32_t i = 0; i < length; ++i) {
574         const CFormItem &obj = cpointer[i];
575         const uint8_t *objBytes = reinterpret_cast<const uint8_t *>(&obj);
576         blob.insert(blob.end(), objBytes, objBytes + sizeof(CFormItem));
577         blob.insert(blob.end(), obj.name.cStr, obj.name.cStr + obj.name.len);
578         blob.insert(blob.end(), obj.value.cStr, obj.value.cStr + obj.value.len);
579     }
580     return blob;
581 }
582 
BlobToCFormItem(const std::vector<uint8_t> & blob)583 std::vector<CFormItem> BlobToCFormItem(const std::vector<uint8_t> &blob)
584 {
585     std::vector<CFormItem> vec;
586     size_t position = 0;
587     while (position < blob.size()) {
588         CFormItem obj;
589         memcpy_s(&obj, sizeof(CFormItem), blob.data() + position, sizeof(CFormItem));
590         position += sizeof(CFormItem);
591 
592         obj.name.cStr = new char[obj.name.len];
593         memcpy_s(obj.name.cStr, obj.name.len, blob.data() + position, obj.name.len);
594         position += obj.name.len;
595 
596         obj.value.cStr = new char[obj.value.len];
597         memcpy_s(obj.value.cStr, obj.value.len, blob.data() + position, obj.value.len);
598         position += obj.value.len;
599 
600         vec.push_back(obj);
601     }
602     return vec;
603 }
604 
CFileSpecToBlob(const CFileSpec * cpointer,uint32_t length)605 std::vector<uint8_t> CFileSpecToBlob(const CFileSpec *cpointer, uint32_t length)
606 {
607     std::vector<uint8_t> blob;
608     for (uint32_t i = 0; i < length; ++i) {
609         const CFileSpec &obj = cpointer[i];
610         const uint8_t *objBytes = reinterpret_cast<const uint8_t *>(&obj);
611         blob.insert(blob.end(), objBytes, objBytes + sizeof(CFileSpec));
612         blob.insert(blob.end(), obj.name.cStr, obj.name.cStr + obj.name.len);
613         blob.insert(blob.end(), obj.path.cStr, obj.path.cStr + obj.path.len);
614         blob.insert(blob.end(), obj.fileName.cStr, obj.fileName.cStr + obj.fileName.len);
615         blob.insert(blob.end(), obj.mimeType.cStr, obj.mimeType.cStr + obj.mimeType.len);
616         blob.emplace_back(obj.is_user_file);
617     }
618     return blob;
619 }
620 
BlobToCFileSpec(const std::vector<uint8_t> & blob)621 std::vector<CFileSpec> BlobToCFileSpec(const std::vector<uint8_t> &blob)
622 {
623     std::vector<CFileSpec> vec;
624     size_t position = 0;
625     while (position < blob.size()) {
626         CFileSpec obj;
627         memcpy_s(&obj, sizeof(CFileSpec), blob.data() + position, sizeof(CFileSpec));
628         position += sizeof(CFileSpec);
629 
630         obj.name.cStr = new char[obj.name.len];
631         memcpy_s(obj.name.cStr, obj.name.len, blob.data() + position, obj.name.len);
632         position += obj.name.len;
633 
634         obj.path.cStr = new char[obj.path.len];
635         memcpy_s(obj.path.cStr, obj.path.len, blob.data() + position, obj.path.len);
636         position += obj.path.len;
637 
638         obj.fileName.cStr = new char[obj.fileName.len];
639         memcpy_s(obj.fileName.cStr, obj.fileName.len, blob.data() + position, obj.fileName.len);
640         position += obj.fileName.len;
641 
642         obj.mimeType.cStr = new char[obj.mimeType.len];
643         memcpy_s(obj.mimeType.cStr, obj.mimeType.len, blob.data() + position, obj.mimeType.len);
644         position += obj.mimeType.len;
645 
646         obj.is_user_file = blob[position];
647         position += 1;
648 
649         vec.push_back(obj);
650     }
651     return vec;
652 }
653 
CEachFileStatusToBlob(const CEachFileStatus * cpointer,uint32_t length)654 std::vector<uint8_t> CEachFileStatusToBlob(const CEachFileStatus *cpointer, uint32_t length)
655 {
656     std::vector<uint8_t> blob;
657     for (uint32_t i = 0; i < length; ++i) {
658         const CEachFileStatus &obj = cpointer[i];
659         const uint8_t *objBytes = reinterpret_cast<const uint8_t *>(&obj);
660         blob.insert(blob.end(), objBytes, objBytes + sizeof(CEachFileStatus));
661         blob.insert(blob.end(), obj.path.cStr, obj.path.cStr + obj.path.len);
662         blob.insert(blob.end(), &obj.reason, &obj.reason + sizeof(uint8_t));
663         blob.insert(blob.end(), obj.message.cStr, obj.message.cStr + obj.message.len);
664     }
665     return blob;
666 }
667 
BlobToCEachFileStatus(const std::vector<uint8_t> & blob)668 std::vector<CEachFileStatus> BlobToCEachFileStatus(const std::vector<uint8_t> &blob)
669 {
670     std::vector<CEachFileStatus> vec;
671     size_t position = 0;
672     while (position < blob.size()) {
673         CEachFileStatus obj;
674         memcpy_s(&obj, sizeof(CEachFileStatus), blob.data() + position, sizeof(CEachFileStatus));
675         position += sizeof(CEachFileStatus);
676 
677         obj.path.cStr = new char[obj.path.len];
678         memcpy_s(obj.path.cStr, obj.path.len, blob.data() + position, obj.path.len);
679         position += obj.path.len;
680 
681         memcpy_s(&obj.reason, sizeof(uint8_t), blob.data() + position, sizeof(uint8_t));
682         position += sizeof(uint8_t);
683 
684         obj.message.cStr = new char[obj.message.len];
685         memcpy_s(obj.message.cStr, obj.message.len, blob.data() + position, obj.message.len);
686         position += obj.message.len;
687 
688         vec.push_back(obj);
689     }
690     return vec;
691 }
692 
CStringToBlob(const CStringWrapper * cpointer,uint32_t length)693 std::vector<uint8_t> CStringToBlob(const CStringWrapper *cpointer, uint32_t length)
694 {
695     std::vector<uint8_t> blob;
696     for (uint32_t i = 0; i < length; ++i) {
697         const CStringWrapper &obj = cpointer[i];
698         blob.push_back(static_cast<uint8_t>(obj.len));
699         blob.insert(blob.end(), obj.cStr, obj.cStr + obj.len);
700     }
701     return blob;
702 }
703 
BlobToStringVec(const std::vector<uint8_t> & blob)704 std::vector<std::string> BlobToStringVec(const std::vector<uint8_t> &blob)
705 {
706     std::vector<std::string> vec;
707     uint32_t position = 0;
708     while (position < blob.size()) {
709         uint32_t len = static_cast<uint32_t>(blob[position++]);
710         std::string str(blob.begin() + position, blob.begin() + position + len);
711         position += len;
712 
713         vec.push_back(std::move(str));
714     }
715 
716     return vec;
717 }
718 
719 // convert vector<CFormItem> to vector<FormItem>
VecToFormItem(const std::vector<CFormItem> & cvec)720 std::vector<FormItem> VecToFormItem(const std::vector<CFormItem> &cvec)
721 {
722     std::vector<FormItem> vec;
723     for (const CFormItem &obj : cvec) {
724         FormItem formItem;
725         formItem.name = std::string(obj.name.cStr, obj.name.len);
726         formItem.value = std::string(obj.value.cStr, obj.value.len);
727         vec.push_back(std::move(formItem));
728         //release memory of obj(new)
729         delete[] obj.name.cStr;
730         delete[] obj.value.cStr;
731     }
732     return vec;
733 }
734 
735 // convert vector<CFileSpec> to vector<FileSpec>
VecToFileSpec(const std::vector<CFileSpec> & cvec)736 std::vector<FileSpec> VecToFileSpec(const std::vector<CFileSpec> &cvec)
737 {
738     std::vector<FileSpec> vec;
739     for (const CFileSpec &obj : cvec) {
740         FileSpec fileSpec;
741         fileSpec.name = std::string(obj.name.cStr, obj.name.len);
742         fileSpec.path = std::string(obj.path.cStr, obj.path.len);
743         fileSpec.fileName = std::string(obj.fileName.cStr, obj.fileName.len);
744         fileSpec.mimeType = std::string(obj.mimeType.cStr, obj.mimeType.len);
745         fileSpec.is_user_file = obj.is_user_file;
746         vec.push_back(std::move(fileSpec));
747         //release memory of obj(new)
748         delete[] obj.name.cStr;
749         delete[] obj.path.cStr;
750         delete[] obj.fileName.cStr;
751         delete[] obj.mimeType.cStr;
752     }
753     return vec;
754 }
755 
756 // convert vector<CEachFileStatus> to vector<EachFileStatus>
VecToEachFileStatus(const std::vector<CEachFileStatus> & cvec)757 std::vector<EachFileStatus> VecToEachFileStatus(const std::vector<CEachFileStatus> &cvec)
758 {
759     std::vector<EachFileStatus> vec;
760     for (const CEachFileStatus &obj : cvec) {
761         EachFileStatus eachFileStatus;
762         eachFileStatus.path = std::string(obj.path.cStr, obj.path.len);
763         eachFileStatus.reason = obj.reason;
764         eachFileStatus.message = std::string(obj.message.cStr, obj.message.len);
765         vec.push_back(std::move(eachFileStatus));
766         //release memory of obj(new)
767         delete[] obj.path.cStr;
768         delete[] obj.message.cStr;
769     }
770     return vec;
771 }
772 
WriteUpdateData(OHOS::NativeRdb::ValuesBucket & insertValues,T * info)773 template<typename T> bool WriteUpdateData(OHOS::NativeRdb::ValuesBucket &insertValues, T *info)
774 {
775     std::vector<uint8_t> eachFileStatusBlob = CEachFileStatusToBlob(info->eachFileStatusPtr, info->eachFileStatusLen);
776     // write to insertValues
777     insertValues.PutString("mime_type", std::string(info->mimeType.cStr, info->mimeType.len));
778     insertValues.PutInt("state", info->progress.commonData.state);
779     insertValues.PutLong("idx", info->progress.commonData.index);
780     insertValues.PutLong("total_processed", info->progress.commonData.totalProcessed);
781     insertValues.PutString("sizes", std::string(info->progress.sizes.cStr, info->progress.sizes.len));
782     insertValues.PutString("processed", std::string(info->progress.processed.cStr, info->progress.processed.len));
783     insertValues.PutString("extras", std::string(info->progress.extras.cStr, info->progress.extras.len));
784     insertValues.PutBlob("each_file_status", eachFileStatusBlob);
785     return true;
786 }
787 
WriteMutableData(OHOS::NativeRdb::ValuesBucket & insertValues,CTaskInfo * taskInfo,CTaskConfig * taskConfig)788 bool WriteMutableData(OHOS::NativeRdb::ValuesBucket &insertValues, CTaskInfo *taskInfo, CTaskConfig *taskConfig)
789 {
790     insertValues.PutLong("mtime", taskInfo->commonData.mtime);
791     insertValues.PutInt("reason", taskInfo->commonData.reason);
792     insertValues.PutLong("tries", taskInfo->commonData.tries);
793     if (!WriteUpdateData(insertValues, taskInfo)) {
794         return false;
795     }
796     // write vectors
797     insertValues.PutBlob("form_items", CFormItemToBlob(taskConfig->formItemsPtr, taskConfig->formItemsLen));
798     insertValues.PutBlob("file_specs", CFileSpecToBlob(taskConfig->fileSpecsPtr, taskConfig->fileSpecsLen));
799     insertValues.PutBlob("body_file_names", CStringToBlob(taskConfig->bodyFileNamesPtr, taskConfig->bodyFileNamesLen));
800     insertValues.PutBlob("certs_paths", CStringToBlob(taskConfig->certsPathPtr, taskConfig->certsPathLen));
801     return true;
802 }
803 
GetLong(std::shared_ptr<OHOS::NativeRdb::ResultSet> resultSet,int line)804 inline int64_t GetLong(std::shared_ptr<OHOS::NativeRdb::ResultSet> resultSet, int line)
805 {
806     int64_t value = 0;
807     resultSet->GetLong(line, value);
808     return value;
809 }
810 
GetInt(std::shared_ptr<OHOS::NativeRdb::ResultSet> resultSet,int line)811 inline int GetInt(std::shared_ptr<OHOS::NativeRdb::ResultSet> resultSet, int line)
812 {
813     int value = 0;
814     resultSet->GetInt(line, value);
815     return value;
816 }
817 
FillCommonTaskInfo(std::shared_ptr<OHOS::NativeRdb::ResultSet> set,TaskInfo & info)818 void FillCommonTaskInfo(std::shared_ptr<OHOS::NativeRdb::ResultSet> set, TaskInfo &info)
819 {
820     info.commonData.taskId = static_cast<uint32_t>(GetLong(set, 0));    // Line 0 is 'task_id'
821     info.commonData.uid = static_cast<uint64_t>(GetLong(set, 1));       // Line 1 is 'uid'
822     info.commonData.action = static_cast<uint8_t>(GetInt(set, 2));      // Line 2 is 'action'
823     info.commonData.mode = static_cast<uint8_t>(GetInt(set, 3));        // Line 3 is 'mode'
824     info.commonData.ctime = static_cast<uint64_t>(GetLong(set, 4));     // Line 4 is 'ctime'
825     info.commonData.mtime = static_cast<uint64_t>(GetLong(set, 5));     // Line 5 is 'mtime'
826     info.commonData.reason = static_cast<uint8_t>(GetInt(set, 6));      // Line 6 is 'reason'
827     info.commonData.gauge = static_cast<bool>(GetInt(set, 7));          // Line 7 is 'gauge'
828     info.commonData.retry = static_cast<bool>(GetInt(set, 8));          // Line 8 is 'retry'
829     info.commonData.tries = static_cast<uint64_t>(GetLong(set, 9));     // Line 9 is 'tries'
830     info.commonData.version = static_cast<uint8_t>(GetLong(set, 10));   // Line 10 is 'version'
831     info.commonData.priority = static_cast<uint32_t>(GetLong(set, 11)); // Line 11 is 'priority'
832 }
833 
FillOtherTaskInfo(std::shared_ptr<OHOS::NativeRdb::ResultSet> set,TaskInfo & info)834 void FillOtherTaskInfo(std::shared_ptr<OHOS::NativeRdb::ResultSet> set, TaskInfo &info)
835 {
836     set->GetString(12, info.bundle);      // Line 12 is 'bundle'
837     set->GetString(13, info.url);         // Line 13 is 'url'
838     set->GetString(14, info.data);        // Line 14 is 'data'
839     set->GetString(15, info.token);       // Line 15 is 'token'
840     set->GetString(16, info.title);       // Line 16 is 'title'
841     set->GetString(17, info.description); // Line 17 is 'description'
842     set->GetString(18, info.mimeType);    // Line 18 is 'mime_type'
843 
844     info.progress.commonData.state = static_cast<uint8_t>(GetInt(set, 19));  // Line 19 here is 'state'
845     info.progress.commonData.index = static_cast<uint8_t>(GetLong(set, 20)); // Line 20 here is 'idx'
846     uintptr_t totalProcessed = static_cast<uintptr_t>(GetLong(set, 21));     // Line 21 is 'totalProcessed'
847     info.progress.commonData.totalProcessed = totalProcessed;
848 
849     set->GetString(22, info.progress.sizes);     // Line 22 here is 'sizes'
850     set->GetString(23, info.progress.processed); // Line 23 here is 'processed'
851     set->GetString(24, info.progress.extras);    // Line 24 here is 'extras'
852 
853     std::vector<uint8_t> formItemsBlob;
854     std::vector<uint8_t> formSpecsBlob;
855     std::vector<uint8_t> eachFileStatusBlob;
856 
857     set->GetBlob(25, formItemsBlob); // Line 25 is 'form_items'
858     info.formItems = VecToFormItem(BlobToCFormItem(formItemsBlob));
859     set->GetBlob(26, formSpecsBlob); // Line 26 is 'file_specs'
860     info.fileSpecs = VecToFileSpec(BlobToCFileSpec(formSpecsBlob));
861     set->GetBlob(27, eachFileStatusBlob); // Line 27 is 'each_file_status'
862     info.eachFileStatus = VecToEachFileStatus(BlobToCEachFileStatus(eachFileStatusBlob));
863 }
864 
BuildCProgress(const Progress & progress)865 CProgress BuildCProgress(const Progress &progress)
866 {
867     return CProgress{
868         .commonData = progress.commonData,
869         .sizes = WrapperCString(progress.sizes),
870         .processed = WrapperCString(progress.processed),
871         .extras = WrapperCString(progress.extras),
872     };
873 }
874 
BuildCTaskInfo(const TaskInfo & taskInfo)875 CTaskInfo *BuildCTaskInfo(const TaskInfo &taskInfo)
876 {
877     uint32_t formItemsLen = taskInfo.formItems.size();
878     CFormItem *formItemsPtr = new CFormItem[formItemsLen];
879     for (uint32_t i = 0; i < formItemsLen; i++) {
880         formItemsPtr[i].name = WrapperCString(taskInfo.formItems[i].name);
881         formItemsPtr[i].value = WrapperCString(taskInfo.formItems[i].value);
882     }
883 
884     uint32_t fileSpecsLen = taskInfo.fileSpecs.size();
885     CFileSpec *fileSpecsPtr = new CFileSpec[fileSpecsLen];
886     CEachFileStatus *eachFileStatusPtr = new CEachFileStatus[fileSpecsLen];
887     for (uint32_t i = 0; i < fileSpecsLen; i++) {
888         fileSpecsPtr[i].name = WrapperCString(taskInfo.fileSpecs[i].name);
889         fileSpecsPtr[i].path = WrapperCString(taskInfo.fileSpecs[i].path);
890         fileSpecsPtr[i].fileName = WrapperCString(taskInfo.fileSpecs[i].fileName);
891         fileSpecsPtr[i].mimeType = WrapperCString(taskInfo.fileSpecs[i].mimeType);
892         fileSpecsPtr[i].is_user_file = taskInfo.fileSpecs[i].is_user_file;
893         eachFileStatusPtr[i].path = WrapperCString(taskInfo.eachFileStatus[i].path);
894         eachFileStatusPtr[i].reason = taskInfo.eachFileStatus[i].reason;
895         eachFileStatusPtr[i].message = WrapperCString(taskInfo.eachFileStatus[i].message);
896     }
897 
898     CTaskInfo *cTaskInfo = new CTaskInfo;
899     cTaskInfo->bundle = WrapperCString(taskInfo.bundle);
900     cTaskInfo->url = WrapperCString(taskInfo.url);
901     cTaskInfo->data = WrapperCString(taskInfo.data);
902     cTaskInfo->token = WrapperCString(taskInfo.token);
903     cTaskInfo->formItemsPtr = formItemsPtr;
904     cTaskInfo->formItemsLen = formItemsLen;
905     cTaskInfo->fileSpecsPtr = fileSpecsPtr;
906     cTaskInfo->fileSpecsLen = fileSpecsLen;
907     cTaskInfo->title = WrapperCString(taskInfo.title);
908     cTaskInfo->description = WrapperCString(taskInfo.description);
909     cTaskInfo->mimeType = WrapperCString(taskInfo.mimeType);
910     cTaskInfo->progress = BuildCProgress(taskInfo.progress);
911     cTaskInfo->eachFileStatusPtr = eachFileStatusPtr;
912     cTaskInfo->eachFileStatusLen = fileSpecsLen;
913     cTaskInfo->commonData = taskInfo.commonData;
914     return cTaskInfo;
915 }
916 
BuildRequestTaskConfigWithLong(std::shared_ptr<OHOS::NativeRdb::ResultSet> set,TaskConfig & config)917 void BuildRequestTaskConfigWithLong(std::shared_ptr<OHOS::NativeRdb::ResultSet> set, TaskConfig &config)
918 {
919     config.commonData.taskId = static_cast<uint32_t>(GetLong(set, 0));    // Line 0 is 'task_id'
920     config.commonData.uid = static_cast<uint64_t>(GetLong(set, 1));       // Line 1 is 'uid'
921     config.commonData.tokenId = static_cast<uint64_t>(GetLong(set, 2));   // Line 2 is 'token_id'
922     config.commonData.index = static_cast<uint32_t>(GetLong(set, 11));    // Line 11 is 'config_idx'
923     config.commonData.begins = static_cast<uint64_t>(GetLong(set, 12));   // Line 12 is 'begins'
924     config.commonData.ends = static_cast<int64_t>(GetLong(set, 13));      // Line 13 is 'ends'
925     config.commonData.priority = static_cast<uint32_t>(GetLong(set, 16)); // Line 16 is 'priority'
926 }
927 
BuildRequestTaskConfigWithInt(std::shared_ptr<OHOS::NativeRdb::ResultSet> set,TaskConfig & config)928 void BuildRequestTaskConfigWithInt(std::shared_ptr<OHOS::NativeRdb::ResultSet> set, TaskConfig &config)
929 {
930     config.commonData.action = static_cast<uint8_t>(GetInt(set, 3));   // Line 3 is 'action'
931     config.commonData.mode = static_cast<uint8_t>(GetInt(set, 4));     // Line 4 is 'mode'
932     config.commonData.cover = static_cast<bool>(GetInt(set, 5));       // Line 5 is 'cover'
933     config.commonData.network = static_cast<uint8_t>(GetInt(set, 6));  // Line 6 is 'network'
934     config.commonData.metered = static_cast<bool>(GetInt(set, 7));     // Line 7 is 'metered'
935     config.commonData.roaming = static_cast<bool>(GetInt(set, 8));     // Line 8 is 'roaming'
936     config.commonData.retry = static_cast<bool>(GetInt(set, 9));       // Line 9 is 'retry'
937     config.commonData.redirect = static_cast<bool>(GetInt(set, 10));   // Line 10 is 'redirect'
938     config.commonData.gauge = static_cast<bool>(GetInt(set, 14));      // Line 14 is 'gauge'
939     config.commonData.precise = static_cast<bool>(GetInt(set, 15));    // Line 15 is 'precise'
940     config.commonData.background = static_cast<bool>(GetInt(set, 17)); // Line 17 is 'background'
941     config.version = static_cast<uint8_t>(GetInt(set, 27));            // Line 27 is 'version'
942     config.bundleType = static_cast<uint8_t>(GetInt(set, 34));         // Line 34 is 'bundle_type'
943 }
944 
BuildRequestTaskConfigWithString(std::shared_ptr<OHOS::NativeRdb::ResultSet> set,TaskConfig & config)945 void BuildRequestTaskConfigWithString(std::shared_ptr<OHOS::NativeRdb::ResultSet> set, TaskConfig &config)
946 {
947     set->GetString(18, config.bundle);          // Line 18 is 'bundle'
948     set->GetString(19, config.url);             // Line 19 is 'url'
949     set->GetString(20, config.title);           // Line 20 is 'title'
950     set->GetString(21, config.description);     // Line 21 is 'description'
951     set->GetString(22, config.method);          // Line 22 is 'method'
952     set->GetString(23, config.headers);         // Line 23 is 'headers'
953     set->GetString(24, config.data);            // Line 24 is 'data'
954     set->GetString(25, config.token);           // Line 25 is 'token'
955     set->GetString(26, config.extras);          // Line 26 is 'config_extras'
956     set->GetString(32, config.proxy);           // Line 32 is 'proxy'
957     set->GetString(33, config.certificatePins); // Line 33 is 'certificate_pins'
958     set->GetString(35, config.atomicAccount);   // Line 35 is 'atomic_account'
959 }
960 
BuildRequestTaskConfigWithBlob(std::shared_ptr<OHOS::NativeRdb::ResultSet> set,TaskConfig & config)961 void BuildRequestTaskConfigWithBlob(std::shared_ptr<OHOS::NativeRdb::ResultSet> set, TaskConfig &config)
962 {
963     std::vector<uint8_t> formItemsBlob;
964     std::vector<uint8_t> formSpecsBlob;
965     std::vector<uint8_t> bodyFileNamesBlob;
966     std::vector<uint8_t> certsPathsBlob;
967 
968     set->GetBlob(28, formItemsBlob); // Line 28 is 'form_items'
969     config.formItems = VecToFormItem(BlobToCFormItem(formItemsBlob));
970     set->GetBlob(29, formSpecsBlob); // Line 29 is 'file_specs'
971     config.fileSpecs = VecToFileSpec(BlobToCFileSpec(formSpecsBlob));
972     set->GetBlob(30, bodyFileNamesBlob); // Line 30 is 'body_file_names'
973     config.bodyFileNames = BlobToStringVec(bodyFileNamesBlob);
974     set->GetBlob(31, certsPathsBlob); // Line 31 is 'certs_paths'
975     config.certsPath = BlobToStringVec(certsPathsBlob);
976 }
977 
BuildRequestTaskConfig(std::shared_ptr<OHOS::NativeRdb::ResultSet> resultSet)978 TaskConfig BuildRequestTaskConfig(std::shared_ptr<OHOS::NativeRdb::ResultSet> resultSet)
979 {
980     TaskConfig taskConfig;
981     BuildRequestTaskConfigWithLong(resultSet, taskConfig);
982     BuildRequestTaskConfigWithInt(resultSet, taskConfig);
983     BuildRequestTaskConfigWithString(resultSet, taskConfig);
984     BuildRequestTaskConfigWithBlob(resultSet, taskConfig);
985     return taskConfig;
986 }
987 } // anonymous namespace
988 
RecordRequestTask(CTaskInfo * taskInfo,CTaskConfig * taskConfig)989 bool RecordRequestTask(CTaskInfo *taskInfo, CTaskConfig *taskConfig)
990 {
991     REQUEST_HILOGD("write to request_task");
992     OHOS::NativeRdb::ValuesBucket insertValues;
993     insertValues.PutLong("task_id", taskConfig->commonData.taskId);
994     insertValues.PutLong("uid", taskConfig->commonData.uid);
995     insertValues.PutLong("token_id", taskConfig->commonData.tokenId);
996     insertValues.PutInt("action", taskConfig->commonData.action);
997     insertValues.PutInt("mode", taskConfig->commonData.mode);
998     insertValues.PutInt("cover", taskConfig->commonData.cover);
999     insertValues.PutInt("network", taskConfig->commonData.network);
1000     insertValues.PutInt("metered", taskConfig->commonData.metered);
1001     insertValues.PutInt("roaming", taskConfig->commonData.roaming);
1002     insertValues.PutLong("ctime", taskInfo->commonData.ctime);
1003     insertValues.PutInt("gauge", taskConfig->commonData.gauge);
1004     insertValues.PutInt("retry", taskInfo->commonData.retry);
1005     insertValues.PutInt("redirect", taskConfig->commonData.redirect);
1006     insertValues.PutInt("version", taskConfig->version);
1007     insertValues.PutLong("config_idx", taskConfig->commonData.index);
1008     insertValues.PutLong("begins", taskConfig->commonData.begins);
1009     insertValues.PutLong("ends", taskConfig->commonData.ends);
1010     insertValues.PutInt("precise", taskConfig->commonData.precise);
1011     insertValues.PutLong("priority", taskConfig->commonData.priority);
1012     insertValues.PutInt("background", taskConfig->commonData.background);
1013     insertValues.PutString("bundle", std::string(taskConfig->bundle.cStr, taskConfig->bundle.len));
1014     insertValues.PutString("url", std::string(taskConfig->url.cStr, taskConfig->url.len));
1015     insertValues.PutString("data", std::string(taskConfig->data.cStr, taskConfig->data.len));
1016     insertValues.PutString("token", std::string(taskConfig->token.cStr, taskConfig->token.len));
1017     insertValues.PutString("proxy", std::string(taskConfig->proxy.cStr, taskConfig->proxy.len));
1018     insertValues.PutString(
1019         "certificate_pins", std::string(taskConfig->certificatePins.cStr, taskConfig->certificatePins.len));
1020     insertValues.PutString("title", std::string(taskConfig->title.cStr, taskConfig->title.len));
1021     insertValues.PutString("description", std::string(taskConfig->description.cStr, taskConfig->description.len));
1022     insertValues.PutString("method", std::string(taskConfig->method.cStr, taskConfig->method.len));
1023     insertValues.PutString("headers", std::string(taskConfig->headers.cStr, taskConfig->headers.len));
1024     insertValues.PutString("config_extras", std::string(taskConfig->extras.cStr, taskConfig->extras.len));
1025     insertValues.PutInt("bundle_type", taskConfig->bundleType);
1026     insertValues.PutString(
1027         "atomic_account", std::string(taskConfig->atomicAccount.cStr, taskConfig->atomicAccount.len));
1028     if (!WriteMutableData(insertValues, taskInfo, taskConfig)) {
1029         REQUEST_HILOGE("write blob data failed");
1030         return false;
1031     }
1032     if (!OHOS::Request::RequestDataBase::GetInstance(OHOS::Request::DB_NAME, true)
1033              .Insert(std::string("request_task"), insertValues)) {
1034         REQUEST_HILOGE("insert to request_task failed, task_id: %{public}d", taskConfig->commonData.taskId);
1035         return false;
1036     }
1037     REQUEST_HILOGD("insert to request_task success");
1038     return true;
1039 }
1040 
UpdateRequestTask(uint32_t taskId,CUpdateInfo * updateInfo)1041 bool UpdateRequestTask(uint32_t taskId, CUpdateInfo *updateInfo)
1042 {
1043     REQUEST_HILOGD("update request_task");
1044     OHOS::NativeRdb::ValuesBucket values;
1045     values.PutLong("mtime", updateInfo->mtime);
1046     values.PutLong("tries", updateInfo->tries);
1047     std::vector<uint8_t> eachFileStatusBlob =
1048         CEachFileStatusToBlob(updateInfo->eachFileStatusPtr, updateInfo->eachFileStatusLen);
1049     // write to insertValues
1050     values.PutString("mime_type", std::string(updateInfo->mimeType.cStr, updateInfo->mimeType.len));
1051     values.PutLong("idx", updateInfo->progress.commonData.index);
1052     values.PutLong("total_processed", updateInfo->progress.commonData.totalProcessed);
1053     values.PutString("processed", std::string(updateInfo->progress.processed.cStr, updateInfo->progress.processed.len));
1054     values.PutString("extras", std::string(updateInfo->progress.extras.cStr, updateInfo->progress.extras.len));
1055     values.PutBlob("each_file_status", eachFileStatusBlob);
1056 
1057     OHOS::NativeRdb::RdbPredicates rdbPredicates("request_task");
1058     rdbPredicates.EqualTo("task_id", std::to_string(taskId));
1059     if (!OHOS::Request::RequestDataBase::GetInstance(OHOS::Request::DB_NAME, true).Update(values, rdbPredicates)) {
1060         REQUEST_HILOGE("update table1 failed, task_id: %{public}d", taskId);
1061         return false;
1062     }
1063     return true;
1064 }
1065 
UpdateRequestTaskState(uint32_t taskId,CUpdateStateInfo * updateStateInfo)1066 bool UpdateRequestTaskState(uint32_t taskId, CUpdateStateInfo *updateStateInfo)
1067 {
1068     REQUEST_HILOGD("Change task state, tid: %{public}d, state is %{public}d", taskId, updateStateInfo->state);
1069     OHOS::NativeRdb::ValuesBucket values;
1070     values.PutLong("mtime", updateStateInfo->mtime);
1071     values.PutInt("state", updateStateInfo->state);
1072     values.PutInt("reason", updateStateInfo->reason);
1073 
1074     OHOS::NativeRdb::RdbPredicates rdbPredicates("request_task");
1075     rdbPredicates.EqualTo("task_id", std::to_string(taskId));
1076     if (!OHOS::Request::RequestDataBase::GetInstance(OHOS::Request::DB_NAME, true).Update(values, rdbPredicates)) {
1077         REQUEST_HILOGE("Change request_task state failed, taskid: %{public}d", taskId);
1078         return false;
1079     }
1080     return true;
1081 }
1082 
GetTaskInfoInner(const OHOS::NativeRdb::RdbPredicates & rdbPredicates,TaskInfo & taskInfo)1083 int GetTaskInfoInner(const OHOS::NativeRdb::RdbPredicates &rdbPredicates, TaskInfo &taskInfo)
1084 {
1085     auto resultSet =
1086         OHOS::Request::RequestDataBase::GetInstance(OHOS::Request::DB_NAME, true)
1087             .Query(rdbPredicates, { "task_id", "uid", "action", "mode", "ctime", "mtime", "reason", "gauge", "retry",
1088                                       "tries", "version", "priority", "bundle", "url", "data", "token", "title",
1089                                       "description", "mime_type", "state", "idx", "total_processed", "sizes",
1090                                       "processed", "extras", "form_items", "file_specs", "each_file_status" });
1091     if (resultSet == nullptr || resultSet->GoToFirstRow() != OHOS::NativeRdb::E_OK) {
1092         REQUEST_HILOGE("result set is nullptr or go to first row failed");
1093         return OHOS::Request::QUERY_ERR;
1094     }
1095     FillCommonTaskInfo(resultSet, taskInfo);
1096     FillOtherTaskInfo(resultSet, taskInfo);
1097     resultSet->Close();
1098     return OHOS::Request::QUERY_OK;
1099 }
1100 
GetTaskInfo(uint32_t taskId)1101 CTaskInfo *GetTaskInfo(uint32_t taskId)
1102 {
1103     OHOS::NativeRdb::RdbPredicates rdbPredicates("request_task");
1104     rdbPredicates.EqualTo("task_id", std::to_string(taskId));
1105 
1106     TaskInfo taskInfo;
1107     if (GetTaskInfoInner(rdbPredicates, taskInfo) == OHOS::Request::QUERY_ERR) {
1108         REQUEST_HILOGE("QueryRequestTaskInfo failed: result set is nullptr or go to first row failed, "
1109                        "task_id: %{public}d",
1110             taskId);
1111         return nullptr;
1112     }
1113 
1114     return BuildCTaskInfo(taskInfo);
1115 }
1116 
BuildCTaskConfig(CTaskConfig * cTaskConfig,const TaskConfig & taskConfig)1117 void BuildCTaskConfig(CTaskConfig *cTaskConfig, const TaskConfig &taskConfig)
1118 {
1119     cTaskConfig->bundle = WrapperCString(taskConfig.bundle);
1120     cTaskConfig->url = WrapperCString(taskConfig.url);
1121     cTaskConfig->title = WrapperCString(taskConfig.title);
1122     cTaskConfig->description = WrapperCString(taskConfig.description);
1123     cTaskConfig->method = WrapperCString(taskConfig.method);
1124     cTaskConfig->headers = WrapperCString(taskConfig.headers);
1125     cTaskConfig->data = WrapperCString(taskConfig.data);
1126     cTaskConfig->token = WrapperCString(taskConfig.token);
1127     cTaskConfig->extras = WrapperCString(taskConfig.extras);
1128     cTaskConfig->proxy = WrapperCString(taskConfig.proxy);
1129     cTaskConfig->certificatePins = WrapperCString(taskConfig.certificatePins);
1130     cTaskConfig->version = taskConfig.version;
1131     cTaskConfig->bundleType = taskConfig.bundleType;
1132     cTaskConfig->atomicAccount = WrapperCString(taskConfig.atomicAccount);
1133 
1134     uint32_t formItemsLen = taskConfig.formItems.size();
1135     CFormItem *formItemsPtr = new CFormItem[formItemsLen];
1136     for (uint32_t j = 0; j < formItemsLen; j++) {
1137         formItemsPtr[j].name = WrapperCString(taskConfig.formItems[j].name);
1138         formItemsPtr[j].value = WrapperCString(taskConfig.formItems[j].value);
1139     }
1140     uint32_t fileSpecsLen = taskConfig.fileSpecs.size();
1141     CFileSpec *fileSpecsPtr = new CFileSpec[fileSpecsLen];
1142     for (uint32_t j = 0; j < fileSpecsLen; j++) {
1143         fileSpecsPtr[j].name = WrapperCString(taskConfig.fileSpecs[j].name);
1144         fileSpecsPtr[j].path = WrapperCString(taskConfig.fileSpecs[j].path);
1145         fileSpecsPtr[j].fileName = WrapperCString(taskConfig.fileSpecs[j].fileName);
1146         fileSpecsPtr[j].mimeType = WrapperCString(taskConfig.fileSpecs[j].mimeType);
1147         fileSpecsPtr[j].is_user_file = taskConfig.fileSpecs[j].is_user_file;
1148     }
1149     uint32_t bodyFileNamesLen = taskConfig.bodyFileNames.size();
1150     CStringWrapper *bodyFileNamesPtr = new CStringWrapper[bodyFileNamesLen];
1151     for (uint32_t j = 0; j < bodyFileNamesLen; j++) {
1152         bodyFileNamesPtr[j] = WrapperCString(taskConfig.bodyFileNames[j]);
1153     }
1154 
1155     uint32_t certsPathLen = taskConfig.certsPath.size();
1156     CStringWrapper *certsPathPtr = new CStringWrapper[certsPathLen];
1157     for (uint32_t j = 0; j < certsPathLen; j++) {
1158         certsPathPtr[j] = WrapperCString(taskConfig.certsPath[j]);
1159     }
1160 
1161     cTaskConfig->formItemsPtr = formItemsPtr;
1162     cTaskConfig->formItemsLen = formItemsLen;
1163     cTaskConfig->fileSpecsPtr = fileSpecsPtr;
1164     cTaskConfig->fileSpecsLen = fileSpecsLen;
1165     cTaskConfig->bodyFileNamesPtr = bodyFileNamesPtr;
1166     cTaskConfig->bodyFileNamesLen = bodyFileNamesLen;
1167     cTaskConfig->certsPathPtr = certsPathPtr;
1168     cTaskConfig->certsPathLen = certsPathLen;
1169     cTaskConfig->commonData = taskConfig.commonData;
1170 }
1171 
QueryTaskConfig(uint32_t taskId)1172 CTaskConfig *QueryTaskConfig(uint32_t taskId)
1173 {
1174     OHOS::NativeRdb::RdbPredicates rdbPredicates("request_task");
1175     rdbPredicates.EqualTo("task_id", std::to_string(taskId));
1176     OHOS::Request::RequestDataBase &database =
1177         OHOS::Request::RequestDataBase::GetInstance(OHOS::Request::DB_NAME, true);
1178     auto resultSet = database.Query(rdbPredicates,
1179         { "task_id", "uid", "token_id", "action", "mode", "cover", "network", "metered", "roaming", "retry", "redirect",
1180             "config_idx", "begins", "ends", "gauge", "precise", "priority", "background", "bundle", "url", "title",
1181             "description", "method", "headers", "data", "token", "config_extras", "version", "form_items", "file_specs",
1182             "body_file_names", "certs_paths", "proxy", "certificate_pins", "bundle_type", "atomic_account" });
1183     int rowCount = 0;
1184     if (resultSet == nullptr) {
1185         REQUEST_HILOGE("QuerySingleTaskConfig failed: result set is nullptr");
1186         return nullptr;
1187     }
1188     int errCode = resultSet->GetRowCount(rowCount);
1189     if (errCode != OHOS::NativeRdb::E_OK) {
1190         REQUEST_HILOGE("TaskConfig result count row failed");
1191         database.CheckAndRebuildDataBase(errCode);
1192         return nullptr;
1193     }
1194     if (rowCount == 0) {
1195         REQUEST_HILOGE("TaskConfig result count row is 0");
1196         return nullptr;
1197     }
1198     if (resultSet->GoToRow(0) != OHOS::NativeRdb::E_OK) {
1199         REQUEST_HILOGE("TaskConfig result set go to 0 row failed");
1200         return nullptr;
1201     }
1202 
1203     TaskConfig taskConfig = BuildRequestTaskConfig(resultSet);
1204     REQUEST_HILOGD(
1205         "QuerySingleTaskConfig in, after BuildRequestTaskConfig, task_id: %{public}u", taskConfig.commonData.taskId);
1206     CTaskConfig *cTaskConfig = new CTaskConfig;
1207     BuildCTaskConfig(cTaskConfig, taskConfig);
1208     return cTaskConfig;
1209 }