• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "sqlite_relational_database_upgrader.h"
17 
18 #include "db_constant.h"
19 #include "db_errno.h"
20 #include "relational_schema_object.h"
21 #include "log_table_manager_factory.h"
22 
23 namespace DistributedDB {
SqliteRelationalDatabaseUpgrader(sqlite3 * db)24 SqliteRelationalDatabaseUpgrader::SqliteRelationalDatabaseUpgrader(sqlite3 *db)
25     : db_(db)
26 {}
27 
~SqliteRelationalDatabaseUpgrader()28 SqliteRelationalDatabaseUpgrader::~SqliteRelationalDatabaseUpgrader() {}
29 
Upgrade()30 int SqliteRelationalDatabaseUpgrader::Upgrade()
31 {
32     int errCode = BeginUpgrade();
33     if (errCode != E_OK) {
34         LOGE("[Relational][Upgrade] Begin upgrade failed. err=%d", errCode);
35         return errCode;
36     }
37 
38     errCode = ExecuteUpgrade();
39     if (errCode != E_OK) {
40         LOGE("[Relational][Upgrade] Execute upgrade failed. err=%d", errCode);
41         (void)EndUpgrade(false);
42         return errCode;
43     }
44 
45     errCode = EndUpgrade(true);
46     if (errCode != E_OK) {
47         LOGE("[Relational][Upgrade] End upgrade failed. err=%d", errCode);
48     }
49     return errCode;
50 }
51 
BeginUpgrade()52 int SqliteRelationalDatabaseUpgrader::BeginUpgrade()
53 {
54     return SQLiteUtils::BeginTransaction(db_, TransactType::IMMEDIATE);
55 }
56 
ExecuteUpgrade()57 int SqliteRelationalDatabaseUpgrader::ExecuteUpgrade()
58 {
59     std::string logTableVersion;
60     int errCode = SQLiteUtils::GetLogTableVersion(db_, logTableVersion);
61     if (errCode != E_OK) {
62         LOGW("[Relational][Upgrade] Get log table version return %d", errCode);
63         return (errCode == -E_NOT_FOUND) ? E_OK : errCode;
64     }
65 
66     errCode = UpgradeLogTable(logTableVersion);
67     if (errCode != E_OK) {
68         LOGE("[Relational][Upgrade] Upgrade log table failed, err = %d.", errCode);
69         return errCode;
70     }
71 
72     return UpgradeTrigger(logTableVersion);
73 }
74 
EndUpgrade(bool isSuccess)75 int SqliteRelationalDatabaseUpgrader::EndUpgrade(bool isSuccess)
76 {
77     if (isSuccess) {
78         return SQLiteUtils::CommitTransaction(db_);
79     }
80 
81     return SQLiteUtils::RollbackTransaction(db_);
82 }
83 
IsNewestVersion(const std::string & logTableVersion)84 bool SqliteRelationalDatabaseUpgrader::IsNewestVersion(const std::string &logTableVersion)
85 {
86     return logTableVersion == DBConstant::LOG_TABLE_VERSION_CURRENT;
87 }
88 
UpgradeTrigger(const std::string & logTableVersion)89 int SqliteRelationalDatabaseUpgrader::UpgradeTrigger(const std::string &logTableVersion)
90 {
91     if (IsNewestVersion(logTableVersion)) {
92         LOGD("[Relational][Upgrade] No need upgrade trigger.");
93         return E_OK;
94     }
95 
96     // get schema from meta
97     std::string schemaDefine;
98     int errCode = SQLiteUtils::GetRelationalSchema(db_, schemaDefine);
99     if (errCode != E_OK) {
100         LOGW("[Relational][Upgrade] Get relational schema from meta return %d.", errCode);
101         return (errCode == -E_NOT_FOUND) ? E_OK : errCode;
102     }
103 
104     RelationalSchemaObject schemaObject;
105     errCode = schemaObject.ParseFromSchemaString(schemaDefine);
106     if (errCode != E_OK) {
107         LOGE("[Relational][Upgrade] Parse to relational schema failed.", errCode);
108         return errCode;
109     }
110 
111     DistributedTableMode mode = schemaObject.GetTableMode();
112     for (const auto &[tableName, tableInfo] : schemaObject.GetTables()) {
113         std::string dropTriggerSql = "DROP TRIGGER IF EXISTS " + DBConstant::SYSTEM_TABLE_PREFIX + tableName +
114             "_ON_UPDATE";
115         errCode = SQLiteUtils::ExecuteRawSQL(db_, dropTriggerSql);
116         if (errCode != E_OK) {
117             LOGE("[Relational][Upgrade] drop trigger failed.", errCode);
118             return errCode;
119         }
120         auto manager = LogTableManagerFactory::GetTableManager(mode, tableInfo.GetTableSyncType());
121         errCode = manager->AddRelationalLogTableTrigger(db_, tableInfo, "");
122         if (errCode != E_OK) {
123             LOGE("[Relational][Upgrade] recreate trigger failed.", errCode);
124             return errCode;
125         }
126     }
127     return E_OK;
128 }
129 
NoNeedUpdateLogTable(const std::string & logTableVersion)130 static bool inline NoNeedUpdateLogTable(const std::string &logTableVersion)
131 {
132     return logTableVersion > DBConstant::LOG_TABLE_VERSION_2;
133 }
134 
UpgradeLogTable(const std::string & logTableVersion)135 int SqliteRelationalDatabaseUpgrader::UpgradeLogTable(const std::string &logTableVersion)
136 {
137     if (NoNeedUpdateLogTable(logTableVersion)) {
138         LOGD("[Relational][Upgrade] No need upgrade log table.");
139         return E_OK;
140     }
141 
142     // get schema from meta
143     std::string schemaDefine;
144     int errCode = SQLiteUtils::GetRelationalSchema(db_, schemaDefine);
145     if (errCode != E_OK) {
146         LOGW("[Relational][UpgradeLogTable] Get relational schema from meta return %d.", errCode);
147         return (errCode == -E_NOT_FOUND) ? E_OK : errCode;
148     }
149 
150     RelationalSchemaObject schemaObject;
151     errCode = schemaObject.ParseFromSchemaString(schemaDefine);
152     if (errCode != E_OK) {
153         LOGE("[Relational][UpgradeLogTable] Parse to relational schema failed.", errCode);
154         return errCode;
155     }
156 
157     for (const auto &item : schemaObject.GetTables()) {
158         std::string addColumnSql = "alter table " + DBConstant::RELATIONAL_PREFIX + item.first +
159             "_log add cloud_gid text after hash_key;";
160         errCode = SQLiteUtils::ExecuteRawSQL(db_, addColumnSql);
161         if (errCode != E_OK) {
162             LOGE("[Relational][UpgradeLogTable] add column failed.", errCode);
163             return errCode;
164         }
165     }
166     return E_OK;
167 }
168 } // namespace DistributedDB