• 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 
16 #include "cloud_sync_log_table_manager.h"
17 
18 namespace DistributedDB {
CalcPrimaryKeyHash(const std::string & references,const TableInfo & table,const std::string & identity)19 std::string CloudSyncLogTableManager::CalcPrimaryKeyHash(const std::string &references, const TableInfo &table,
20     const std::string &identity)
21 {
22     (void)identity;
23     std::string sql;
24     if (table.GetPrimaryKey().size() == 1) {
25         sql = "calc_hash(" + references + "'" + table.GetPrimaryKey().at(0)  + "')";
26     }  else {
27         std::set<std::string> primaryKeySet; // we need sort primary key by name
28         for (const auto &it : table.GetPrimaryKey()) {
29             primaryKeySet.emplace(it.second);
30         }
31         sql = "calc_hash(";
32         for (const auto &it : primaryKeySet) {
33             sql += "calc_hash(" + references + "'" + it + "')||";
34         }
35         sql.pop_back();
36         sql.pop_back();
37         sql += ")";
38     }
39     return sql;
40 }
41 
GetIndexSql(const TableInfo & table,std::vector<std::string> & schema)42 void CloudSyncLogTableManager::GetIndexSql(const TableInfo &table, std::vector<std::string> &schema)
43 {
44     const std::string tableName = GetLogTableName(table);
45 
46     std::string indexTimestampFlagGid = "CREATE INDEX IF NOT EXISTS " + tableName +
47         "_cloud_time_flag_gid_index ON " + tableName + "(timestamp, flag, cloud_gid);";
48     std::string indexGid = "CREATE INDEX IF NOT EXISTS " + tableName +
49         "_cloud_gid_index ON " + tableName + "(cloud_gid);";
50     schema.emplace_back(indexTimestampFlagGid);
51     schema.emplace_back(indexGid);
52 }
53 
GetPrimaryKeySql(const TableInfo & table)54 std::string CloudSyncLogTableManager::GetPrimaryKeySql(const TableInfo &table)
55 {
56     return "PRIMARY KEY(hash_key)";
57 }
58 
59 // The parameter "identity" is a hash string that identifies a device. The same for the next two functions.
GetInsertTrigger(const TableInfo & table,const std::string & identity)60 std::string CloudSyncLogTableManager::GetInsertTrigger(const TableInfo &table, const std::string &identity)
61 {
62     std::string logTblName = GetLogTableName(table);
63     std::string insertTrigger = "CREATE TRIGGER IF NOT EXISTS ";
64     insertTrigger += "naturalbase_rdb_" + table.GetTableName() + "_ON_INSERT AFTER INSERT \n";
65     insertTrigger += "ON '" + table.GetTableName() + "'\n";
66     insertTrigger += "WHEN (SELECT count(*) from " + DBConstant::RELATIONAL_PREFIX + "metadata ";
67     insertTrigger += "WHERE key = 'log_trigger_switch' AND value = 'true')\n";
68     insertTrigger += "BEGIN\n";
69     insertTrigger += "\t INSERT OR REPLACE INTO " + logTblName;
70     insertTrigger += " (data_key, device, ori_device, timestamp, wtimestamp, flag, hash_key, cloud_gid)";
71     insertTrigger += " VALUES (new.rowid, '', '',";
72     insertTrigger += " get_raw_sys_time(), get_raw_sys_time(), 0x02, ";
73     insertTrigger += CalcPrimaryKeyHash("NEW.", table, identity) + ", CASE WHEN (SELECT count(*)<>0 FROM ";
74     insertTrigger += logTblName + " where hash_key = " + CalcPrimaryKeyHash("NEW.", table, identity);
75     insertTrigger += ") THEN (select cloud_gid from " + logTblName + " where hash_key = ";
76     insertTrigger += CalcPrimaryKeyHash("NEW.", table, identity) + ") ELSE '' END);\n";
77     insertTrigger += "END;";
78     return insertTrigger;
79 }
80 
GetUpdateTrigger(const TableInfo & table,const std::string & identity)81 std::string CloudSyncLogTableManager::GetUpdateTrigger(const TableInfo &table, const std::string &identity)
82 {
83     (void)identity;
84     std::string logTblName = GetLogTableName(table);
85     std::string updateTrigger = "CREATE TRIGGER IF NOT EXISTS ";
86     updateTrigger += "naturalbase_rdb_" + table.GetTableName() + "_ON_UPDATE AFTER UPDATE \n";
87     updateTrigger += "ON '" + table.GetTableName() + "'\n";
88     updateTrigger += "WHEN (SELECT count(*) from " + DBConstant::RELATIONAL_PREFIX + "metadata ";
89     updateTrigger += "WHERE key = 'log_trigger_switch' AND value = 'true')\n";
90     updateTrigger += "BEGIN\n"; // if user change the primary key, we can still use gid to identify which one is updated
91     updateTrigger += "\t UPDATE " + logTblName;
92     updateTrigger += " SET timestamp=get_raw_sys_time(), device='', flag=0x02";
93     updateTrigger += " WHERE data_key = OLD.rowid;\n";
94     updateTrigger += "END;";
95     return updateTrigger;
96 }
97 
GetDeleteTrigger(const TableInfo & table,const std::string & identity)98 std::string CloudSyncLogTableManager::GetDeleteTrigger(const TableInfo &table, const std::string &identity)
99 {
100     (void)identity;
101     std::string deleteTrigger = "CREATE TRIGGER IF NOT EXISTS ";
102     deleteTrigger += "naturalbase_rdb_" + table.GetTableName() + "_ON_DELETE BEFORE DELETE \n";
103     deleteTrigger += "ON '" + table.GetTableName() + "'\n";
104     deleteTrigger += "WHEN (SELECT count(*) from " + DBConstant::RELATIONAL_PREFIX + "metadata ";
105     deleteTrigger += "WHERE key = 'log_trigger_switch' AND VALUE = 'true')\n";
106     deleteTrigger += "BEGIN\n";
107     deleteTrigger += "\t UPDATE " + GetLogTableName(table);
108     deleteTrigger += " SET data_key=-1,flag=0x03,timestamp=get_raw_sys_time()";
109     deleteTrigger += " WHERE data_key = OLD.rowid;";
110     deleteTrigger += "END;";
111     return deleteTrigger;
112 }
113 } // DistributedDB