1 /*
2  * Copyright (c) 2021-2024 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 #ifndef HIVIEW_BASE_EVENT_STORE_INCLUDE_SYS_EVENT_QUERY_H
17 #define HIVIEW_BASE_EVENT_STORE_INCLUDE_SYS_EVENT_QUERY_H
18 
19 #ifndef DllExport
20 #define DllExport
21 #endif // DllExport
22 
23 #include <functional>
24 #include <queue>
25 #include <memory>
26 #include <string>
27 #include <variant>
28 #include <vector>
29 
30 #include "base_def.h"
31 #include "doc_query.h"
32 #include "sys_event.h"
33 
34 namespace OHOS {
35 namespace HiviewDFX {
36 namespace EventStore {
37 /* Object returned by the event query */
38 struct Entry {
39     /* Event sequence */
40     int64_t id = 0;
41 
42     /* Event timestamp */
43     int64_t ts = 0;
44 
45     /* Event data */
46     std::shared_ptr<EventRaw::RawData> data = nullptr;
47 
48     std::string sysVersion;
49 
50     std::string patchVersion;
51 
EntryEntry52     Entry(int64_t id, int64_t ts, std::shared_ptr<EventRaw::RawData> data)
53         : id(id), ts(ts), data(data), sysVersion("") {}
54 
EntryEntry55     Entry(int64_t id, int64_t ts, std::shared_ptr<EventRaw::RawData> data,
56         std::string& sysVersion, std::string& patchVersion)
57         : id(id), ts(ts), data(data), sysVersion(sysVersion), patchVersion(patchVersion) {}
58 };
59 using CompareFunc = bool(*)(const Entry&, const Entry&);
60 using EntryQueue = std::priority_queue<Entry, std::vector<Entry>, CompareFunc>;
61 
62 enum DbQueryStatus { SUCCEED = 0, CONCURRENT, OVER_TIME, OVER_LIMIT, TOO_FREQENTLY };
63 using DbQueryTag = struct {
64     bool isInnerQuery;
65     bool needFrequenceCheck;
66 };
67 using DbQueryCallback = std::function<void(DbQueryStatus)>;
68 using QueryProcessInfo = std::pair<pid_t, std::string>; // first: pid of process, second: process name
69 
70 constexpr pid_t INNER_PROCESS_ID = -1;
71 
72 enum Op { NONE = 0, EQ = 1, NE, LT, LE, GT, GE, SW, NSW };
73 
74 class SysEventDao;
75 class SysEventDatabase;
76 
77 class FieldNumber final {
78 public:
79     enum ValueType { DOUBLE = 0, UINT = 1, INT = 2 };
80 
81     template<typename T>
FieldNumber(T val)82     FieldNumber(T val)
83     {
84         if constexpr (std::is_same_v<std::decay_t<T>, uint8_t> ||
85             std::is_same_v<std::decay_t<T>, uint16_t> ||
86             std::is_same_v<std::decay_t<T>, uint32_t> ||
87             std::is_same_v<std::decay_t<T>, uint64_t>) {
88                 val_ = static_cast<uint64_t>(val);
89                 return;
90         }
91         if constexpr (std::is_same_v<std::decay_t<T>, int8_t> ||
92             std::is_same_v<std::decay_t<T>, int16_t> ||
93             std::is_same_v<std::decay_t<T>, int32_t> ||
94             std::is_same_v<std::decay_t<T>, int64_t>) {
95                 val_ = static_cast<int64_t>(val);
96                 return;
97         }
98         if constexpr (std::is_same_v<std::decay_t<T>, float> ||
99             std::is_same_v<std::decay_t<T>, double>) {
100                 val_ = static_cast<double>(val);
101                 return;
102         }
103         val_ = static_cast<int64_t>(0); // default
104     }
105 
106     bool operator==(const FieldNumber& fieldNum) const;
107     bool operator!=(const FieldNumber& fieldNum) const;
108     bool operator<(const FieldNumber& fieldNum) const;
109     bool operator<=(const FieldNumber& fieldNum) const;
110     bool operator>(const FieldNumber& fieldNum) const;
111     bool operator>=(const FieldNumber& fieldNum) const;
112 
113     template<typename T,
114         std::enable_if_t<std::is_same_v<std::decay_t<T>, double> ||
115         std::is_same_v<std::decay_t<T>, uint64_t> ||
116         std::is_same_v<std::decay_t<T>, int64_t>>* = nullptr>
decltype(auto)117     decltype(auto) GetNumber() const
118     {
119         if (val_.index() == DOUBLE) {
120             return static_cast<std::decay_t<T>>(std::get<DOUBLE>(val_));
121         }
122         if (val_.index() == UINT) {
123             return static_cast<std::decay_t<T>>(std::get<UINT>(val_));
124         }
125         return static_cast<std::decay_t<T>>(std::get<INT>(val_));
126     }
127 
128     std::string FormatAsString() const;
129     ValueType Index() const;
130 
131 private:
132     std::variant<double, uint64_t, int64_t> val_;
133 };
134 
135 class FieldValue {
136 public:
137     enum ValueType { STRING = 0, NUMBER = 1 };
138 
FieldValue()139     FieldValue(): FieldValue(0) {}
140 
141     template<typename T>
FieldValue(T val)142     FieldValue(T val)
143     {
144         if constexpr (std::is_same_v<std::decay_t<T>, uint8_t> ||
145             std::is_same_v<std::decay_t<T>, uint16_t> ||
146             std::is_same_v<std::decay_t<T>, uint32_t> ||
147             std::is_same_v<std::decay_t<T>, uint64_t> ||
148             std::is_same_v<std::decay_t<T>, int8_t> ||
149             std::is_same_v<std::decay_t<T>, int16_t> ||
150             std::is_same_v<std::decay_t<T>, int32_t> ||
151             std::is_same_v<std::decay_t<T>, int64_t> ||
152             std::is_same_v<std::decay_t<T>, float> ||
153             std::is_same_v<std::decay_t<T>, double>) {
154             val_ = val;
155             return;
156         }
157         if constexpr (std::is_same_v<std::decay_t<T>, std::string> ||
158             std::is_same_v<std::decay_t<T>, const char*>) {
159             val_ = std::string(val);
160             return;
161         }
162         val_ = 0;
163     }
164 
~FieldValue()165     ~FieldValue() {}
166 
167     bool operator==(const FieldValue& fieldValue) const;
168     bool operator!=(const FieldValue& fieldValue) const;
169     bool operator<(const FieldValue& fieldValue) const;
170     bool operator<=(const FieldValue& fieldValue) const;
171     bool operator>(const FieldValue& fieldValue) const;
172     bool operator>=(const FieldValue& fieldValue) const;
173     bool IsStartWith(const FieldValue& fieldValue) const;
174     bool IsNotStartWith(const FieldValue& fieldValue) const;
175 
176     bool IsNumber() const;
177     bool IsString() const;
178     FieldNumber GetFieldNumber() const;
179     std::string GetString() const;
180     std::string FormatAsString() const;
181     ValueType Index() const;
182 
183 private:
184     std::variant<std::string, FieldNumber> val_;
185 };
186 
187 class DllExport Cond {
188 public:
Cond()189     Cond(): op_(NONE), fieldValue_(0) {}
~Cond()190     ~Cond() {}
191 
192     template <typename T>
Cond(const std::string & col,Op op,const T & value)193     Cond(const std::string &col, Op op, const T &value): col_(col), op_(op), fieldValue_(value) {}
194 
195     template <typename T>
And(const std::string & col,Op op,const T & value)196     Cond &And(const std::string &col, Op op, const T &value)
197     {
198         andConds_.emplace_back(Cond(col, op, value));
199         return *this;
200     }
201     Cond &And(const Cond &cond);
202 
203     std::string ToString() const;
204 
205 private:
206     friend class DocQuery;
207     friend class SysEventQuery;
208     static bool IsSimpleCond(const Cond &cond);
209     static void Traval(DocQuery &docQuery, const Cond &cond);
210 
211 private:
212     std::string col_;
213     Op op_;
214     FieldValue fieldValue_;
215     std::vector<Cond> andConds_;
216 };  // Cond
217 
218 class DllExport ResultSet {
219 public:
220     ResultSet();
221     ResultSet(ResultSet &&result);
222     ResultSet& operator = (ResultSet &&result);
223     ~ResultSet();
224 
225 public:
226     using RecordIter = std::vector<SysEvent>::iterator;
227     int GetErrCode() const;
228     bool HasNext() const;
229     RecordIter Next();
230 
231 private:
232     friend class SysEventQuery;
233     friend class SysEventQueryWrapper;
234     void Set(int code, bool has);
235     std::vector<SysEvent> eventRecords_;
236     RecordIter iter_;
237     int code_;
238     bool has_;
239 };  // ResultSet
240 
241 /* Query parameters for filtering file names */
242 struct SysEventQueryArg {
243     std::string domain;
244     std::vector<std::string> names;
245     uint32_t type;
246     int64_t toSeq;
247     int64_t fromSeq;
248 
SysEventQueryArgSysEventQueryArg249     SysEventQueryArg() : SysEventQueryArg("", {}, 0, INVALID_VALUE_INT, INVALID_VALUE_INT) {}
SysEventQueryArgSysEventQueryArg250     SysEventQueryArg(const std::string& domain, const std::vector<std::string>& names,
251         uint32_t type, int64_t toSeq, int64_t fromSeq)
252     {
253         this->domain = domain;
254         this->names.assign(names.begin(), names.end());
255         this->type = type;
256         this->toSeq = toSeq;
257         this->fromSeq = fromSeq;
258     }
~SysEventQueryArgSysEventQueryArg259     ~SysEventQueryArg() {}
260 };
261 
262 class DllExport SysEventQuery {
263 public:
264     SysEventQuery(const std::string& domain, const std::vector<std::string>& names);
~SysEventQuery()265     virtual ~SysEventQuery() {}
266 
267     SysEventQuery &Select(const std::vector<std::string> &eventCols);
268 
269     template <typename T>
Where(const std::string & col,Op op,const T & value)270     SysEventQuery &Where(const std::string &col, Op op, const T &value)
271     {
272         cond_.And(col, op, value);
273         return *this;
274     }
275     SysEventQuery &Where(const Cond &cond);
276 
277     template <typename T>
And(const std::string & col,Op op,const T & value)278     SysEventQuery &And(const std::string &col, Op op, const T &value)
279     {
280         cond_.And(col, op, value);
281         return *this;
282     }
283     SysEventQuery &And(const Cond &cond);
284 
285     SysEventQuery &Order(const std::string &col, bool isAsc = true);
286 
287     virtual ResultSet Execute(int limit = 100, DbQueryTag tag = { true, true },
288         QueryProcessInfo callerInfo = std::make_pair(INNER_PROCESS_ID, ""),
289         DbQueryCallback queryCallback = nullptr);
290 
291     std::string ToString() const;
292 
293     friend class SysEventDao;
294     friend class SysEventDatabase;
295 
296 protected:
297     SysEventQuery();
298     SysEventQuery(const std::string& domain, const std::vector<std::string>& names, uint32_t type, int64_t toSeq,
299         int64_t fromSeq);
300 
301 private:
302     void BuildDocQuery(DocQuery &docQuery) const;
303     CompareFunc CreateCompareFunc() const;
304 
305     int limit_;
306     std::pair<std::string, bool> orderCol_;
307     Cond cond_;
308     SysEventQueryArg queryArg_;
309     std::string version_;
310 }; // SysEventQuery
311 } // EventStore
312 } // namespace HiviewDFX
313 } // namespace OHOS
314 #endif // HIVIEW_BASE_EVENT_STORE_INCLUDE_SYS_EVENT_QUERY_H
315