1/*
2 * Copyright (C) 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 "rdb_opkey_callback.h"
17
18#include "data_storage_errors.h"
19#include "data_storage_log_wrapper.h"
20#include "opkey_data.h"
21#include "parser_util.h"
22#include "preferences_util.h"
23#include "rdb_errno.h"
24#include "rdb_store.h"
25#include "string"
26#include "values_bucket.h"
27
28namespace OHOS {
29namespace Telephony {
30int RdbOpKeyCallback::OnUpgrade(NativeRdb::RdbStore &rdbStore, int oldVersion, int newVersion)
31{
32    DATA_STORAGE_LOGI(
33        "Data_Storage RdbOpKeyCallback::OnUpgrade##oldVersion = %d, "
34        "newVersion = %d\n",
35        oldVersion, newVersion);
36    return NativeRdb::E_OK;
37}
38
39int RdbOpKeyCallback::OnDowngrade(NativeRdb::RdbStore &rdbStore, int currentVersion, int targetVersion)
40{
41    DATA_STORAGE_LOGI(
42        "Data_Storage RdbOpKeyCallback::OnDowngrade##currentVersion = "
43        "%d, targetVersion = %d\n",
44        currentVersion, targetVersion);
45    return NativeRdb::E_OK;
46}
47
48int RdbOpKeyCallback::OnCreate(NativeRdb::RdbStore &rdbStore)
49{
50    DATA_STORAGE_LOGI("RdbOpKeyCallback::OnCreate");
51    RdbBaseCallBack::OnCreate(rdbStore);
52    InitData(rdbStore, TABLE_OPKEY_INFO);
53    return NativeRdb::E_OK;
54}
55
56int RdbOpKeyCallback::OnOpen(NativeRdb::RdbStore &rdbStore)
57{
58    DATA_STORAGE_LOGI("RdbOpKeyCallback::OnOpen");
59    return NativeRdb::E_OK;
60}
61
62int64_t RdbOpKeyCallback::InitData(NativeRdb::RdbStore &rdbStore, const std::string &tableName)
63{
64    DATA_STORAGE_LOGI("InitData::start");
65    ParserUtil util;
66    std::vector<OpKey> vec;
67    std::string path;
68    util.GetOpKeyFilePath(path);
69    if (path.empty()) {
70        DATA_STORAGE_LOGE("InitData fail! path empty!");
71        return DATA_STORAGE_ERROR;
72    }
73    std::string checksum;
74    util.GetFileChecksum(path.c_str(), checksum);
75    if (checksum.empty()) {
76        DATA_STORAGE_LOGE("InitData fail! checksum is null!");
77        return DATA_STORAGE_ERROR;
78    }
79    if (!IsOpKeyDbUpdateNeeded(checksum)) {
80        DATA_STORAGE_LOGI("InitData::opkey data has not change.");
81        return DATA_STORAGE_SUCCESS;
82    }
83
84    if (util.ParserOpKeyJson(vec, path.c_str()) != DATA_STORAGE_SUCCESS) {
85        DATA_STORAGE_LOGE("Parse OpKey info fail");
86        return DATA_STORAGE_ERROR;
87    }
88    ClearData(rdbStore);
89    int result = rdbStore.BeginTransaction();
90    if (result != NativeRdb::E_OK) {
91        DATA_STORAGE_LOGE("BeginTransaction error!");
92        return DATA_STORAGE_ERROR;
93    }
94    DATA_STORAGE_LOGD("InitData size = %{public}zu", vec.size());
95    std::vector<NativeRdb::ValuesBucket> valuesBuckets;
96    for (size_t i = 0; i < vec.size(); i++) {
97        NativeRdb::ValuesBucket value;
98        util.ParserOpKeyToValuesBucket(value, vec[i]);
99        valuesBuckets.push_back(value);
100    }
101    int64_t outInsertNum;
102    result = rdbStore.BatchInsert(outInsertNum, tableName, valuesBuckets);
103    if (result == NativeRdb::E_OK) {
104        result = rdbStore.Commit();
105    }
106    if (result != NativeRdb::E_OK) {
107        DATA_STORAGE_LOGE("Commit error!");
108        return DATA_STORAGE_ERROR;
109    }
110    SetPreferOpKeyConfChecksum(checksum);
111    DATA_STORAGE_LOGI("InitData::end insert data: %{public}s", std::to_string(outInsertNum).c_str());
112    return outInsertNum;
113}
114
115int RdbOpKeyCallback::ClearData(NativeRdb::RdbStore &rdbStore)
116{
117    std::string sql;
118    sql.append("delete from ").append(TABLE_OPKEY_INFO);
119    return rdbStore.ExecuteSql(sql);
120}
121
122bool RdbOpKeyCallback::IsOpKeyDbUpdateNeeded(std::string &checkSum)
123{
124    auto preferencesUtil = DelayedSingleton<PreferencesUtil>::GetInstance();
125    if (preferencesUtil != nullptr) {
126        std::string lastCheckSum = preferencesUtil->ObtainString(OPKEY_CONF_CHECKSUM, "");
127        if (checkSum.compare(lastCheckSum) == 0) {
128            return false;
129        }
130    }
131    return true;
132}
133
134int RdbOpKeyCallback::SetPreferOpKeyConfChecksum(std::string &checkSum)
135{
136    auto preferencesUtil = DelayedSingleton<PreferencesUtil>::GetInstance();
137    if (preferencesUtil == nullptr) {
138        DATA_STORAGE_LOGE("preferencesUtil is nullptr!");
139        return NativePreferences::E_ERROR;
140    }
141    return preferencesUtil->SaveString(OPKEY_CONF_CHECKSUM, checkSum);
142}
143} // namespace Telephony
144} // namespace OHOS
145