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 return UpgradeTrigger(logTableVersion);
67 }
68
EndUpgrade(bool isSuccess)69 int SqliteRelationalDatabaseUpgrader::EndUpgrade(bool isSuccess)
70 {
71 if (isSuccess) {
72 return SQLiteUtils::CommitTransaction(db_);
73 }
74
75 return SQLiteUtils::RollbackTransaction(db_);
76 }
77
UpgradeTrigger(const std::string & logTableVersion)78 int SqliteRelationalDatabaseUpgrader::UpgradeTrigger(const std::string &logTableVersion)
79 {
80 if (logTableVersion != DBConstant::LOG_TABLE_VERSION_1) {
81 LOGD("[Relational][Upgrade] No need upgrade trigger.");
82 return E_OK;
83 }
84
85 // get schema from meta
86 std::string schemaDefine;
87 int errCode = SQLiteUtils::GetRelationalSchema(db_, schemaDefine);
88 if (errCode != E_OK) {
89 LOGW("[Relational][Upgrade] Get relational schema from meta return %d.", errCode);
90 return (errCode == -E_NOT_FOUND) ? E_OK : errCode;
91 }
92
93 RelationalSchemaObject schemaObject;
94 errCode = schemaObject.ParseFromSchemaString(schemaDefine);
95 if (errCode != E_OK) {
96 LOGE("[Relational][Upgrade] Parse to relational schema failed.", errCode);
97 return errCode;
98 }
99
100 DistributedTableMode mode = schemaObject.GetTableMode();
101 if (mode != DistributedTableMode::SPLIT_BY_DEVICE) {
102 return E_OK;
103 }
104
105 for (const auto &[tableName, tableInfo] : schemaObject.GetTables()) {
106 std::string dropTriggerSql = "DROP TRIGGER IF EXISTS " + DBConstant::SYSTEM_TABLE_PREFIX + tableName +
107 "_ON_UPDATE";
108 errCode = SQLiteUtils::ExecuteRawSQL(db_, dropTriggerSql);
109 if (errCode != E_OK) {
110 LOGE("[Relational][Upgrade] drop trigger failed.", errCode);
111 return errCode;
112 }
113 auto manager = LogTableManagerFactory::GetTableManager(mode);
114 errCode = manager->AddRelationalLogTableTrigger(db_, tableInfo, "");
115 if (errCode != E_OK) {
116 LOGE("[Relational][Upgrade] recreate trigger failed.", errCode);
117 return errCode;
118 }
119 }
120 return E_OK;
121 }
122 } // namespace DistributedDB