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 #ifdef RELATIONAL_STORE
16 #include "tracker_table.h"
17 #include "schema_constant.h"
18
19 namespace DistributedDB {
Init(const TrackerSchema & schema)20 void TrackerTable::Init(const TrackerSchema &schema)
21 {
22 tableName_ = schema.tableName;
23 extendColName_ = schema.extendColName;
24 trackerColNames_ = schema.trackerColNames;
25 }
26
GetTableName() const27 std::string TrackerTable::GetTableName() const
28 {
29 return tableName_;
30 }
31
GetTrackerColNames() const32 const std::set<std::string> &TrackerTable::GetTrackerColNames() const
33 {
34 return trackerColNames_;
35 }
36
GetAssignValSql(bool isDelete) const37 const std::string TrackerTable::GetAssignValSql(bool isDelete) const
38 {
39 if (extendColName_.empty()) {
40 return "''";
41 }
42 return isDelete ? ("OLD." + extendColName_) : ("NEW." + extendColName_);
43 }
44
GetExtendAssignValSql(bool isDelete) const45 const std::string TrackerTable::GetExtendAssignValSql(bool isDelete) const
46 {
47 if (extendColName_.empty()) {
48 return "";
49 }
50 return isDelete ? (", extend_field = OLD." + extendColName_) : (", extend_field = NEW." + extendColName_);
51 }
52
GetDiffTrackerValSql() const53 const std::string TrackerTable::GetDiffTrackerValSql() const
54 {
55 if (trackerColNames_.empty()) {
56 return "0";
57 }
58 std::string sql = " case when (";
59 size_t index = 0;
60 for (const auto &colName: trackerColNames_) {
61 sql += "(NEW." + colName + " IS NOT OLD." + colName + ")";
62 if (index < trackerColNames_.size() - 1) {
63 sql += " or ";
64 }
65 index++;
66 }
67 sql += ") then 1 else 0 end";
68 return sql;
69 }
70
GetExtendName() const71 const std::string TrackerTable::GetExtendName() const
72 {
73 return extendColName_;
74 }
75
ToString() const76 std::string TrackerTable::ToString() const
77 {
78 std::string attrStr;
79 attrStr += "{";
80 attrStr += R"("NAME": ")" + tableName_ + "\",";
81 attrStr += R"("EXTEND_NAME": ")" + extendColName_ + "\",";
82 attrStr += R"("TRACKER_NAMES": [)";
83 for (const auto &colName: trackerColNames_) {
84 attrStr += "\"" + colName + "\",";
85 }
86 attrStr.pop_back();
87 attrStr += "]}";
88 return attrStr;
89 }
90
GetDropTempTriggerSql() const91 const std::vector<std::string> TrackerTable::GetDropTempTriggerSql() const
92 {
93 if (IsEmpty()) {
94 return {};
95 }
96 std::vector<std::string> dropSql;
97 dropSql.push_back("DROP TRIGGER IF EXISTS " + DBConstant::RELATIONAL_PREFIX + tableName_ + "_ON_INSERT_TEMP;");
98 dropSql.push_back("DROP TRIGGER IF EXISTS " + DBConstant::RELATIONAL_PREFIX + tableName_ + "_ON_UPDATE_TEMP;");
99 dropSql.push_back("DROP TRIGGER IF EXISTS " + DBConstant::RELATIONAL_PREFIX + tableName_ + "_ON_DELETE_TEMP;");
100 return dropSql;
101 }
102
GetTempInsertTriggerSql() const103 const std::string TrackerTable::GetTempInsertTriggerSql() const
104 {
105 // This trigger is built on the log table
106 std::string sql = "CREATE TEMP TRIGGER IF NOT EXISTS " + DBConstant::RELATIONAL_PREFIX + tableName_;
107 sql += "_ON_INSERT_TEMP AFTER INSERT ON " + DBConstant::RELATIONAL_PREFIX + tableName_ + "_log" +
108 " WHEN (SELECT count(1) FROM " + DBConstant::RELATIONAL_PREFIX + "metadata" +
109 " WHERE key = 'log_trigger_switch' AND value = 'false')\n";
110 sql += "BEGIN\n";
111 sql += "UPDATE " + DBConstant::RELATIONAL_PREFIX + tableName_ + "_log" + " SET ";
112 sql += "cursor = (SELECT case when (MAX(cursor) is null) then 1 else MAX(cursor) + 1 END ";
113 sql += "FROM " + DBConstant::RELATIONAL_PREFIX + tableName_ + "_log" + ") WHERE ";
114 sql += " hash_key = NEW.hash_key;\n";
115 if (!IsEmpty()) {
116 sql += "SELECT server_observer('" + tableName_ + "', 1);";
117 }
118 sql += "\nEND;";
119 return sql;
120 }
121
GetTempUpdateTriggerSql() const122 const std::string TrackerTable::GetTempUpdateTriggerSql() const
123 {
124 std::string sql = "CREATE TEMP TRIGGER IF NOT EXISTS " + DBConstant::RELATIONAL_PREFIX + tableName_;
125 sql += "_ON_UPDATE_TEMP AFTER UPDATE ON " + tableName_ +
126 " WHEN (SELECT count(1) FROM " + DBConstant::RELATIONAL_PREFIX + "metadata" +
127 " WHERE key = 'log_trigger_switch' AND value = 'false')\n";
128 sql += "BEGIN\n";
129 sql += "UPDATE " + DBConstant::RELATIONAL_PREFIX + tableName_ + "_log" + " SET ";
130 if (!IsEmpty()) {
131 sql += "extend_field=" + GetAssignValSql() + ",";
132 }
133 sql += " cursor = (SELECT case when (MAX(cursor) is null) then 1 else MAX(cursor) + 1 END ";
134 sql += "FROM " + DBConstant::RELATIONAL_PREFIX + tableName_ + "_log" + ") WHERE ";
135 sql += " data_key = OLD." + std::string(DBConstant::SQLITE_INNER_ROWID) + ";\n";
136 if (!IsEmpty()) {
137 sql += "SELECT server_observer('" + tableName_ + "', " + GetDiffTrackerValSql() + ");";
138 }
139 sql += "\nEND;";
140 return sql;
141 }
142
GetTempDeleteTriggerSql() const143 const std::string TrackerTable::GetTempDeleteTriggerSql() const
144 {
145 std::string sql = "CREATE TEMP TRIGGER IF NOT EXISTS " + DBConstant::RELATIONAL_PREFIX + tableName_;
146 sql += "_ON_DELETE_TEMP AFTER DELETE ON " + tableName_ +
147 " WHEN (SELECT count(1) FROM " + DBConstant::RELATIONAL_PREFIX + "metadata" +
148 " WHERE key = 'log_trigger_switch' AND value = 'false')\n";
149 sql += "BEGIN\n";
150 sql += "UPDATE " + DBConstant::RELATIONAL_PREFIX + tableName_ + "_log" + " SET ";
151 if (!IsEmpty()) {
152 sql += "extend_field=" + GetAssignValSql(true) + ",";
153 }
154 sql += " cursor = (SELECT case when (MAX(cursor) is null) then 1 else MAX(cursor) + 1 END ";
155 sql += "FROM " + DBConstant::RELATIONAL_PREFIX + tableName_ + "_log" + ") WHERE ";
156 sql += " data_key = OLD." + std::string(DBConstant::SQLITE_INNER_ROWID) + ";\n";
157 if (!IsEmpty()) {
158 sql += "SELECT server_observer('" + tableName_ + "', 1);";
159 }
160 sql += "\nEND;";
161 return sql;
162 }
163
GetUpgradedExtendValSql() const164 const std::string TrackerTable::GetUpgradedExtendValSql() const
165 {
166 if (IsEmpty() || extendColName_.empty()) {
167 return "''";
168 }
169 std::string sql = " (SELECT " + extendColName_ + " from " + tableName_ + " WHERE " + tableName_ + "." +
170 std::string(DBConstant::SQLITE_INNER_ROWID) +
171 " = " + DBConstant::RELATIONAL_PREFIX + tableName_ + "_log.data_key) ";
172 return sql;
173 }
174
SetTableName(const std::string & tableName)175 void TrackerTable::SetTableName(const std::string &tableName)
176 {
177 tableName_ = tableName;
178 }
179
SetExtendName(const std::string & colName)180 void TrackerTable::SetExtendName(const std::string &colName)
181 {
182 extendColName_ = colName;
183 }
184
SetTrackerNames(const std::set<std::string> & trackerNames)185 void TrackerTable::SetTrackerNames(const std::set<std::string> &trackerNames)
186 {
187 trackerColNames_ = std::move(trackerNames);
188 }
189
IsEmpty() const190 bool TrackerTable::IsEmpty() const
191 {
192 return trackerColNames_.empty();
193 }
194
IsChanging(const TrackerSchema & schema)195 bool TrackerTable::IsChanging(const TrackerSchema &schema)
196 {
197 if (tableName_ != schema.tableName || extendColName_ != schema.extendColName) {
198 return true;
199 }
200 if (trackerColNames_.size() != schema.trackerColNames.size()) {
201 return true;
202 }
203 for (const auto &col: trackerColNames_) {
204 if (schema.trackerColNames.find(col) == schema.trackerColNames.end()) {
205 return true;
206 }
207 }
208 return false;
209 }
210 }
211 #endif