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 #include "rdb_migrate_mgr.h"
16 #include "app_domain_verify_hilog.h"
17 #include "rdb_errno.h"
18 #include "rdb_store.h"
19 
20 namespace OHOS::AppDomainVerify {
21 constexpr int INNER_VERSION_UNKNOWN = 0;
22 constexpr int INNER_VERSION_1_0 = 1;
23 constexpr int INNER_VERSION_1_0_COL_CNT = 2;
24 constexpr int RDB_VERSION_1 = 1;
25 constexpr int RDB_VERSION_2 = 2;
26 
Upgrade(NativeRdb::RdbStore & rdbStore,int currVersion,int targetVersion)27 int RdbMigrateMgr::Upgrade(NativeRdb::RdbStore& rdbStore, int currVersion, int targetVersion)
28 {
29     APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
30     int ret = NativeRdb::E_OK;
31     if (currVersion == RDB_VERSION_1) {
32         int innerVersion = QueryInnerVersion(rdbStore);
33         if (innerVersion == INNER_VERSION_1_0) {
34             UpgradeFromV1ToV2(rdbStore);
35         }
36         ret = UpgradeFromV2ToV3(rdbStore);
37     } else if (currVersion == RDB_VERSION_2) {
38         ret = UpgradeFromV2ToV3(rdbStore);
39     } else {
40         APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE,
41             "current version:%d is not support", currVersion);
42     }
43     APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called, end");
44     return ret;
45 }
46 
RdbMigrateMgr(const AppDomainVerifyRdbConfig & appDomainVerifyRdbConfig)47 RdbMigrateMgr::RdbMigrateMgr(const AppDomainVerifyRdbConfig& appDomainVerifyRdbConfig)
48 {
49     appDomainVerifyRdbConfig_ = appDomainVerifyRdbConfig;
50 }
QueryInnerVersion(NativeRdb::RdbStore & rdbStore)51 int RdbMigrateMgr::QueryInnerVersion(NativeRdb::RdbStore& rdbStore)
52 {
53     NativeRdb::AbsRdbPredicates absRdbPredicates(appDomainVerifyRdbConfig_.tableName);
54     std::vector<std::string> columns = {};
55     auto absSharedResultSet = rdbStore.Query(absRdbPredicates, columns);
56     if (absSharedResultSet == nullptr) {
57         APP_DOMAIN_VERIFY_HILOGE(
58             APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "QueryInnerVersion query absSharedResultSet failed");
59         return INNER_VERSION_UNKNOWN;
60     }
61     int innerVersion = INNER_VERSION_UNKNOWN;
62     int count = -1;
63     absSharedResultSet->GetColumnCount(count);
64     APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "rdbStore GetColumnCount %{public}d", count);
65     if (count == INNER_VERSION_1_0_COL_CNT) {
66         innerVersion = INNER_VERSION_1_0;
67     }
68     absSharedResultSet->Close();
69     APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "rdbStore innerVersion %{public}d", innerVersion);
70     return innerVersion;
71 }
72 
UpgradeFromV1ToV2(NativeRdb::RdbStore & rdbStore)73 void RdbMigrateMgr::UpgradeFromV1ToV2(NativeRdb::RdbStore& rdbStore)
74 {
75     APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
76     const std::string migrateSqls[] = { R"(drop table IF EXISTS temp_table;)", R"(drop table IF EXISTS final_table;)",
77         R"(CREATE TEMPORARY TABLE temp_table AS
78             SELECT
79               verified_domain.KEY,
80               json_extract(verified_domain.VALUE, '$.appIdentifier') as appid,
81               json_extract(verified_domain.VALUE, '$.hostVerifyStatusMap') as map
82             FROM
83               verified_domain;)",
84         R"(CREATE TABLE final_table AS
85             SELECT
86               temp_table.KEY as BUNDLE_NAME,
87               temp_table.appid as APP_IDENTIFIER,
88               json_each.key AS DOMAIN,
89               json_each.value AS VERIFY_STATUES
90             FROM
91               temp_table,
92               json_each(temp_table.map);)",
93         R"(drop table IF EXISTS verified_domain;)",
94         R"(CREATE TABLE IF NOT EXISTS  verified_domain (ID INTEGER PRIMARY KEY AUTOINCREMENT, BUNDLE_NAME TEXT NOT NULL,
95             APP_IDENTIFIER TEXT,
96             DOMAIN TEXT NOT NULL, VERIFY_STATUES INTEGER);)",
97         R"(INSERT INTO verified_domain (BUNDLE_NAME,APP_IDENTIFIER,DOMAIN,VERIFY_STATUES) select * from final_table;)",
98         R"(drop table IF EXISTS final_table;)" };
99     for (const auto& sql : migrateSqls) {
100         auto ret = rdbStore.ExecuteSql(sql);
101         if (ret != NativeRdb::E_OK) {
102             APP_DOMAIN_VERIFY_HILOGE(
103                 APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "execute sql %{public}s failed.", sql.c_str());
104             auto dropTableSql = R"(drop table IF EXISTS verified_domain;)";
105             (void)rdbStore.ExecuteSql(dropTableSql);
106             APP_DOMAIN_VERIFY_HILOGE(
107                 APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "UpgradeFromV1_0 executeSql failed, ret: %{public}d", ret);
108             break;
109         }
110     }
111     APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
112 }
113 
UpgradeFromV2ToV3(NativeRdb::RdbStore & rdbStore)114 int RdbMigrateMgr::UpgradeFromV2ToV3(NativeRdb::RdbStore& rdbStore)
115 {
116     APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
117     const std::string migrateSqls[] = {
118         R"(ALTER TABLE verified_domain ADD COLUMN VERIFY_TIME TEXT NOT NULL DEFAULT '';)",
119         R"(ALTER TABLE verified_domain ADD COLUMN VERIFY_COUNT INTERGER NULL DEFAULT 0;)",
120     };
121     int ret = ExecSqlWithTrans(rdbStore, [&](NativeRdb::RdbStore& rdbStore)->bool {
122         for (const auto& sql : migrateSqls) {
123             auto ret = rdbStore.ExecuteSql(sql);
124             if (ret != NativeRdb::E_OK) {
125                 APP_DOMAIN_VERIFY_HILOGE(
126                     APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE,
127                     "UpgradeFromV2ToV3 executeSql failed, ret: %{public}d, reason: exec %{public}s fail.",
128                     ret, sql.c_str());
129                 return false;
130             }
131         }
132         return true;
133     });
134     APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called end, ret:%{public}d", ret);
135     return ret;
136 }
137 
ExecSqlWithTrans(NativeRdb::RdbStore & rdbStore,const TransFunc & func)138 int RdbMigrateMgr::ExecSqlWithTrans(NativeRdb::RdbStore& rdbStore, const TransFunc& func)
139 {
140     APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
141     auto ret = rdbStore.BeginTransaction();
142     if (ret != NativeRdb::E_OK) {
143         return ret;
144     }
145     if (func(rdbStore)) {
146         return rdbStore.Commit();
147     }
148     APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "rdb exec roll back");
149     ret = rdbStore.RollBack();
150     if (ret != NativeRdb::E_OK) {
151         APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "rdb exec roll back fail.");
152         return ret;
153     }
154     return NativeRdb::E_ERROR;
155 }
156 
157 }