• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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