Line data Source code
1 : /**
2 : Copyright (c) 2017-2022 Roman Katuntsev <sbkarr@stappler.org>
3 : Copyright (c) 2023-2024 Stappler LLC <admin@stappler.dev>
4 :
5 : Permission is hereby granted, free of charge, to any person obtaining a copy
6 : of this software and associated documentation files (the "Software"), to deal
7 : in the Software without restriction, including without limitation the rights
8 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 : copies of the Software, and to permit persons to whom the Software is
10 : furnished to do so, subject to the following conditions:
11 :
12 : The above copyright notice and this permission notice shall be included in
13 : all copies or substantial portions of the Software.
14 :
15 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 : THE SOFTWARE.
22 : **/
23 :
24 : #ifndef STAPPLER_DB_SPDBQUERY_H_
25 : #define STAPPLER_DB_SPDBQUERY_H_
26 :
27 : #include "SPDb.h"
28 :
29 : namespace STAPPLER_VERSIONIZED stappler::db {
30 :
31 : enum class Resolve {
32 : None = 0,
33 : Files = 2,
34 : Sets = 4,
35 : Objects = 8,
36 : Arrays = 16,
37 : Ids = 32,
38 : Basics = 64,
39 : Defaults = 128,
40 : All = Files | Sets | Objects | Arrays | Defaults,
41 : };
42 :
43 : SP_DEFINE_ENUM_AS_MASK(Resolve);
44 :
45 : class Query : public AllocBase {
46 : public:
47 : struct Field : public AllocBase {
48 : String name;
49 : Vector<Field> fields;
50 :
51 : Field(Field &&);
52 : Field(const Field &);
53 :
54 : Field &operator=(Field &&);
55 : Field &operator=(const Field &);
56 :
57 : template <typename Str> Field(Str &&);
58 : template <typename Str> Field(Str &&, Vector<String> &&);
59 : template <typename Str> Field(Str &&, std::initializer_list<String> &&);
60 : template <typename Str> Field(Str &&, Vector<Field> &&);
61 : template <typename Str> Field(Str &&, std::initializer_list<Field> &&);
62 :
63 : void setName(const char *);
64 : void setName(const StringView &);
65 : void setName(const String &);
66 : void setName(String &&);
67 : void setName(const Field &);
68 : void setName(Field &&);
69 : };
70 :
71 : using FieldsVec = Vector<Field>;
72 :
73 : struct Select : public AllocBase {
74 : Comparation compare = Comparation::Equal;
75 : Value value1;
76 : Value value2;
77 : String field;
78 : FullTextQuery textQuery;
79 :
80 100 : Select() { }
81 : Select(const StringView & f, Comparation c, Value && v1, Value && v2);
82 : Select(const StringView & f, Comparation c, int64_t v1, int64_t v2);
83 : Select(const StringView & f, Comparation c, const String & v);
84 : Select(const StringView & f, Comparation c, const StringView & v);
85 : Select(const StringView & f, Comparation c, FullTextQuery && v);
86 : };
87 :
88 : struct SoftLimit {
89 : String field;
90 : size_t limit;
91 : Value offset;
92 : };
93 :
94 : static Query all();
95 : static Query field(int64_t id, const StringView &);
96 : static Query field(int64_t id, const StringView &, const Query &);
97 :
98 : static Resolve decodeResolve(const StringView &str);
99 : static String encodeResolve(Resolve);
100 :
101 : Query & select(const StringView &alias);
102 : Query & select(int64_t id);
103 : Query & select(const Value &);
104 : Query & select(Vector<int64_t> &&id);
105 : Query & select(SpanView<int64_t> id);
106 : Query & select(std::initializer_list<int64_t> &&id);
107 :
108 : Query & select(const StringView &f, Comparation c, const Value & v1, const Value &v2 = Value());
109 : Query & select(const StringView &f, const Value & v1); // special case for equality
110 :
111 : Query & select(const StringView &f, Comparation c, int64_t v1);
112 : Query & select(const StringView &f, Comparation c, int64_t v1, int64_t v2);
113 : Query & select(const StringView &f, const String & v);
114 : Query & select(const StringView &f, String && v);
115 :
116 : Query & select(const StringView &f, const Bytes & v);
117 : Query & select(const StringView &f, Bytes && v);
118 :
119 : Query & select(const StringView &f, FullTextQuery && v);
120 :
121 : Query & select(Select &&q);
122 :
123 : Query & order(const StringView &f, Ordering o = Ordering::Ascending, size_t limit = stappler::maxOf<size_t>(), size_t offset = 0);
124 : Query & softLimit(const StringView &, Ordering, size_t limit, Value &&);
125 :
126 : Query & first(const StringView &f, size_t limit = 1, size_t offset = 0);
127 : Query & last(const StringView &f, size_t limit = 1, size_t offset = 0);
128 :
129 : Query & limit(size_t l, size_t off);
130 : Query & limit(size_t l);
131 : Query & offset(size_t l);
132 :
133 : Query & delta(uint64_t);
134 : Query & delta(const StringView &);
135 :
136 : template <typename ... Args>
137 : Query & include(Field &&, Args && ...);
138 :
139 : Query & include(Field &&);
140 : Query & exclude(Field &&);
141 :
142 : Query & depth(uint16_t);
143 :
144 : Query & forUpdate();
145 :
146 : Query & clearFields();
147 :
148 : bool empty() const;
149 :
150 : StringView getQueryField() const;
151 : int64_t getQueryId() const;
152 :
153 : int64_t getSingleSelectId() const;
154 : const Vector<int64_t> & getSelectIds() const;
155 : StringView getSelectAlias() const;
156 : const Vector<Select> &getSelectList() const;
157 :
158 : const String & getOrderField() const;
159 : Ordering getOrdering() const;
160 :
161 : size_t getLimitValue() const;
162 : size_t getOffsetValue() const;
163 :
164 : const Value &getSoftLimitValue() const;
165 :
166 : bool hasSelectName() const; // id or alias
167 : bool hasSelectList() const;
168 :
169 : bool hasSelect() const;
170 : bool hasOrder() const;
171 : bool hasLimit() const;
172 : bool hasOffset() const;
173 : bool hasDelta() const;
174 : bool hasFields() const;
175 : bool isForUpdate() const;
176 : bool isSoftLimit() const;
177 :
178 : uint64_t getDeltaToken() const;
179 :
180 : uint16_t getResolveDepth() const;
181 :
182 : const FieldsVec &getIncludeFields() const;
183 : const FieldsVec &getExcludeFields() const;
184 :
185 : Value encode() const;
186 :
187 : protected:
188 : String queryField;
189 : int64_t queryId = 0;
190 :
191 : Vector<int64_t> selectIds;
192 : String selectAlias;
193 : Vector<Select> selectList;
194 :
195 : Ordering ordering = Ordering::Ascending;
196 : String orderField;
197 :
198 : size_t limitValue = stappler::maxOf<size_t>();
199 : size_t offsetValue = 0;
200 : Value softLimitValue;
201 :
202 : uint64_t deltaToken;
203 :
204 : uint16_t resolveDepth = 1;
205 :
206 : FieldsVec fieldsInclude;
207 : FieldsVec fieldsExclude;
208 : bool update = false;
209 : bool _softLimit = false;
210 : bool _selected = false;
211 : };
212 :
213 : template <typename Str>
214 12956 : inline Query::Field::Field(Str &&str) {
215 12956 : setName(std::forward<Str>(str));
216 12956 : }
217 :
218 : template <typename Str>
219 : inline Query::Field::Field(Str &&str, Vector<String> &&l) {
220 : setName(std::forward<Str>(str));
221 : for (auto &it : l) {
222 : fields.emplace_back(std::move(it));
223 : }
224 : }
225 :
226 : template <typename Str>
227 : inline Query::Field::Field(Str &&str, std::initializer_list<String> &&l) {
228 : setName(std::forward<Str>(str));
229 : for (auto &it : l) {
230 : fields.emplace_back(String(std::move(it)));
231 : }
232 : }
233 :
234 : template <typename Str>
235 : inline Query::Field::Field(Str &&str, Vector<Field> &&l) : fields(std::move(l)) {
236 : setName(std::forward<Str>(str));
237 : }
238 :
239 : template <typename Str>
240 : inline Query::Field::Field(Str &&str, std::initializer_list<Field> &&l) {
241 : setName(std::forward<Str>(str));
242 : for (auto &it : l) {
243 : fields.emplace_back(std::move(it));
244 : }
245 : }
246 :
247 : template <typename ... Args>
248 2 : Query & Query::include(Field &&f, Args && ... args) {
249 2 : include(std::move(f));
250 2 : include(std::forward<Args>(args)...);
251 2 : return *this;
252 : }
253 :
254 : }
255 :
256 : #endif /* STAPPLER_DB_SPDBQUERY_H_ */
|