1 /* 2 * Copyright (c) 2021 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 #ifndef SQLITE_QUERY_HELPER_H 16 #define SQLITE_QUERY_HELPER_H 17 18 #include <list> 19 #include <set> 20 #include <string> 21 #include <vector> 22 23 #include "query_expression.h" 24 #include "schema_utils.h" 25 #include "sqlite_import.h" 26 27 namespace DistributedDB { 28 namespace TriggerMode { 29 enum class TriggerModeEnum; 30 } 31 enum class CloudWaterType; 32 struct QueryObjInfo { 33 SchemaObject schema_; 34 std::list<QueryObjNode> queryObjNodes_; 35 std::vector<uint8_t> prefixKey_; 36 std::string suggestIndex_; 37 std::set<Key> keys_; 38 int orderByCounts_ = 0; // Record processing to which orderBy node 39 bool isValid_ = true; 40 bool hasOrderBy_ = false; 41 bool hasLimit_ = false; 42 bool hasPrefixKey_ = false; 43 std::string tableName_; 44 bool isRelationalQuery_ = false; 45 SortType sortType_ = SortType::NONE; 46 }; 47 48 enum class SymbolType : uint32_t { 49 INVALID_SYMBOL = 0x0000, 50 COMPARE_SYMBOL = 0x0100, // relation symbol use to compare 51 RELATIONAL_SYMBOL = 0x0200, 52 RANGE_SYMBOL = 0x0300, 53 PREFIXKEY_SYMBOL = 0x0400, 54 LOGIC_SYMBOL = 0x0500, 55 LINK_SYMBOL = 0x0600, // use to link relatonal symbol 56 SPECIAL_SYMBOL = 0x0700, // need special precess and need at the last 57 SUGGEST_INDEX_SYMBOL = 0x0800, 58 IN_KEYS_SYMBOL = 0x0900, 59 }; 60 61 class SqliteQueryHelper final { 62 public: 63 explicit SqliteQueryHelper(const QueryObjInfo &info); 64 65 // forbidden move constructor. 66 SqliteQueryHelper(SqliteQueryHelper &&) = delete; 67 SqliteQueryHelper &operator=(SqliteQueryHelper &&) = delete; 68 // forbidden copy constructor. 69 SqliteQueryHelper(const SqliteQueryHelper &) = delete; 70 SqliteQueryHelper &operator=(const SqliteQueryHelper &) = delete; 71 72 ~SqliteQueryHelper() = default; 73 74 int GetQuerySqlStatement(sqlite3 *dbHandle, bool onlyRowid, sqlite3_stmt *&statement); 75 int GetQuerySqlStatement(sqlite3 *dbHandle, const std::string &sql, sqlite3_stmt *&statement); 76 int GetCountSqlStatement(sqlite3 *dbHandle, sqlite3_stmt *&countStmt); 77 78 // For query Sync 79 int GetQuerySyncStatement(sqlite3 *dbHandle, uint64_t beginTime, uint64_t endTime, sqlite3_stmt *&statement, 80 bool isCount = false); 81 int GetSyncDataCheckSql(std::string &sql); 82 int BindSyncDataCheckStmt(sqlite3_stmt *statement, const Key &hashKey) const; 83 84 int GetSubscribeSql(const std::string &subscribeId, TriggerMode::TriggerModeEnum mode, 85 std::string &subscribeCondition); 86 87 static SymbolType GetSymbolType(const QueryObjType &queryObjType); 88 89 // public for unit test 90 int GetQuerySql(std::string &sql, bool onlyRowid); 91 int GetCountQuerySql(std::string &sql); 92 GetTableName()93 const std::string &GetTableName() 94 { 95 return tableName_; 96 } 97 98 int GetRelationalMissQuerySql(const std::vector<std::string> &fieldNames, std::string &sql); 99 int GetRelationalMissQueryStatement(sqlite3 *dbHandle, uint64_t beginTime, uint64_t endTime, 100 const std::vector<std::string> &fieldNames, sqlite3_stmt *&statement); 101 int GetRelationalSyncDataQuerySql(std::string &sql, bool hasSubQuery, const std::vector<std::string> &fieldNames); 102 int GetRelationalSyncDataQuerySqlWithLimit(const std::vector<std::string> &fieldNames, std::string &sql); 103 int GetRelationalQueryStatement(sqlite3 *dbHandle, uint64_t beginTime, uint64_t endTime, 104 const std::vector<std::string> &fieldNames, sqlite3_stmt *&statement); 105 std::string GetRelationalCloudQuerySql(const std::vector<Field> &fields, 106 const bool &isCloudForcePush, bool isCompensatedTask, CloudWaterType mode); 107 108 std::string GetCountRelationalCloudQuerySql(bool isCloudForcePush, bool isCompensatedTask, CloudWaterType mode); 109 110 std::string GetGidRelationalCloudQuerySql(const std::vector<Field> &fields, bool isCloudForcePush, 111 bool isCompensatedTask); 112 113 int GetCloudQueryStatement(bool useTimestampAlias, sqlite3 *dbHandle, uint64_t beginTime, std::string &sql, 114 sqlite3_stmt *&statement); 115 116 int GetAndBindGidKvCloudQueryStatement(const std::string &user, sqlite3 *dbHandle, sqlite3_stmt *&stmt); 117 118 int GetCountKvCloudDataStatement(sqlite3 *db, bool forcePush, const CloudWaterType mode, sqlite3_stmt *&stmt); 119 120 std::pair<int, int64_t> BindCountKvCloudDataStatement(sqlite3 *db, bool isMemory, const Timestamp ×tamp, 121 const std::string &user, sqlite3_stmt *&stmt); 122 123 void AppendKvQueryObjectOnSql(std::string &sql); 124 125 std::pair<int, sqlite3_stmt *> GetKvCloudQueryStmt(sqlite3 *db, bool forcePush, const CloudWaterType mode, 126 int64_t timeStamp, const std::string &user); 127 128 static std::string GetKvCloudQuerySql(bool countOnly, bool forcePush); 129 130 static void AppendCloudQueryToGetDiffData(std::string &sql, const CloudWaterType mode, bool isKv = false); 131 132 static std::string GetKvCloudRecordSql(); 133 134 static std::string GetCloudVersionRecordSql(bool isDeviceEmpty); 135 private: 136 int ToQuerySql(); 137 int ToQuerySyncSql(bool hasSubQuery, bool useTimestampAlias = false); 138 int ToGetCountSql(); 139 int ParseQueryExpression(const QueryObjNode &queryNode, std::string &querySql, 140 const std::string &accessStr = "", bool placeholder = true); 141 std::string MapRelationalSymbolToSql(const QueryObjNode &queryNode, bool placeholder = false) const; 142 std::string MapKeywordSymbolToSql(const QueryObjNode &queryNode); 143 std::string MapLogicSymbolToSql(const QueryObjNode &queryNode) const; 144 std::string MapValueToSql(const QueryObjNode &queryNode, bool placeholder) const; 145 std::string MapCastFuncSql(const QueryObjNode &queryNode, const std::string &accessStr = ""); 146 std::string MapCastTypeSql(const FieldType &type) const; 147 int BindFieldValue(sqlite3_stmt *statement, const QueryObjNode &queryNode, int &index) const; 148 bool FilterSymbolToAddBracketLink(std::string &querySql, bool isNeedLink = true) const; 149 std::string AssembleSqlForSuggestIndex(const std::string &baseSql, const std::string &filter) const; 150 std::string CheckAndFormatSuggestIndex() const; 151 int GetSyncDataQuerySql(std::string &sql, bool hasSubQuery, bool isCount); 152 int ParseQueryObjNodeToSQL(bool isQueryForSync); 153 int BindTimeRange(sqlite3_stmt *&statement, int &index, uint64_t beginTime, uint64_t endTime) const; 154 int BindObjNodes(sqlite3_stmt *&statement, int &index) const; 155 int GetSubscribeCondition(const std::string &accessStr, std::string &conditionStr); 156 std::string MapKeysInToSql(size_t keysNum) const; 157 int BindKeysToStmt(const std::set<Key> &keys, sqlite3_stmt *&countStmt, int &index) const; 158 159 std::string MapKeysInSubCondition(const std::string &accessStr) const; // For InKeys. 160 // Return the left string of symbol in compare clause. 161 std::string GetFieldShape(const QueryObjNode &queryNode, const std::string &accessStr = ""); 162 163 void AppendCloudQuery(bool isCloudForcePush, bool isCompensatedTask, std::string &sql, CloudWaterType mode); 164 165 void AppendCloudGidQuery(bool isCloudForcePush, bool isCompensatedTask, std::string &sql); 166 SchemaObject schema_; 167 std::list<QueryObjNode> queryObjNodes_; 168 std::vector<uint8_t> prefixKey_; 169 std::string suggestIndex_; 170 std::string tableName_; 171 std::set<Key> keys_; 172 173 std::string querySql_; 174 std::string countSql_; 175 176 int orderByCounts_; // Record processing to which orderBy node 177 bool isValid_; 178 bool transformed_; 179 bool hasOrderBy_; 180 bool hasLimit_; 181 bool isOrderByAppeared_; 182 bool hasPrefixKey_; 183 bool isNeedOrderbyKey_; // The tag field is used for prefix query filtering key sorting 184 bool isRelationalQuery_; 185 SortType sortType_ = SortType::NONE; 186 }; 187 } 188 #endif