Line data Source code
1 : /**
2 : Copyright (c) 2016-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_SPDBQUERYLIST_H_
25 : #define STAPPLER_DB_SPDBQUERYLIST_H_
26 :
27 : #include "SPDbContinueToken.h"
28 : #include "SPDbQuery.h"
29 :
30 : namespace STAPPLER_VERSIONIZED stappler::db {
31 :
32 : class ApplicationInterface;
33 :
34 : enum class Action {
35 : Get,
36 : Set,
37 : Append,
38 : Remove,
39 : Count,
40 : };
41 :
42 : enum class TransactionStatus {
43 : None,
44 : Commit,
45 : Rollback,
46 : };
47 :
48 : class QueryFieldResolver : public AllocBase {
49 : public:
50 : enum class Meta {
51 : None = 0,
52 : Time = 1,
53 : Action = 2,
54 : View = 4,
55 : };
56 :
57 : QueryFieldResolver();
58 : QueryFieldResolver(const ApplicationInterface *app, const Scheme &, const Query &, const Vector<StringView> &extraFields = Vector<StringView>());
59 :
60 : const Field *getField(const String &) const;
61 : const Scheme *getScheme() const;
62 : const Map<String, Field> *getFields() const;
63 : Meta getMeta() const;
64 :
65 : const Set<const Field *> &getResolves() const;
66 : const Set<StringView> &getResolvesData() const;
67 :
68 : const Query::FieldsVec *getIncludeVec() const;
69 : const Query::FieldsVec *getExcludeVec() const;
70 :
71 : QueryFieldResolver next(const StringView &) const;
72 :
73 : explicit operator bool () const;
74 :
75 : protected:
76 : struct Data {
77 : const Scheme *scheme = nullptr;
78 : const Map<String, Field> *fields = nullptr;
79 : const Query::FieldsVec *include = nullptr;
80 : const Query::FieldsVec *exclude = nullptr;
81 : Set<const Field *> resolved;
82 : Set<StringView> resolvedData;
83 : Map<String, Data> next;
84 : Meta meta = Meta::None;
85 : };
86 :
87 : QueryFieldResolver(Data *);
88 : void doResolve(const ApplicationInterface *app, Data *, const Vector<StringView> &extraFields, uint16_t depth, uint16_t max);
89 : void doResolveData(Data *, uint16_t depth, uint16_t max);
90 :
91 : Data *root = nullptr;
92 : };
93 :
94 : SP_DEFINE_ENUM_AS_MASK(QueryFieldResolver::Meta);
95 :
96 : class QueryList : public AllocBase {
97 : public:
98 : using FieldCallback = stappler::Callback<void(const StringView &name, const Field *f)>;
99 :
100 : static constexpr int64_t DefaultSoftLimit = 25;
101 : static constexpr int64_t MinSoftLimit = 1;
102 : static constexpr int64_t MaxSoftLimit = 500;
103 :
104 : enum Flags {
105 : None,
106 : SimpleGet = 1 << 0,
107 : };
108 :
109 : struct Item {
110 : const Scheme *scheme = nullptr;
111 : const Field *ref = nullptr;
112 : const Field *field = nullptr;
113 :
114 : bool all = false;
115 : bool resolved = false;
116 :
117 : Query query;
118 : QueryFieldResolver fields;
119 :
120 : const Set<const Field *> &getQueryFields() const;
121 : };
122 :
123 : QueryList(const ApplicationInterface *app, const Scheme *);
124 :
125 : bool selectById(const Scheme *, uint64_t);
126 : bool selectByName(const Scheme *, const StringView &);
127 : bool selectByQuery(const Scheme *, Query::Select &&);
128 :
129 : bool order(const Scheme *, const StringView &f, db::Ordering o);
130 : bool first(const Scheme *, const StringView &f, size_t v);
131 : bool last(const Scheme *, const StringView &f, size_t v);
132 : bool limit(const Scheme *, size_t limit);
133 : bool offset(const Scheme *, size_t offset);
134 :
135 : bool setFullTextQuery(const Field *field, FullTextQuery &&);
136 :
137 : bool setAll();
138 : bool setField(const Scheme *, const Field *field);
139 : bool setProperty(const Field *field);
140 :
141 : StringView setQueryAsMtime();
142 :
143 : void clearFlags();
144 : void addFlag(Flags);
145 : bool hasFlag(Flags) const;
146 :
147 : bool isAll() const;
148 : bool isRefSet() const;
149 : bool isObject() const;
150 : bool isView() const;
151 : bool empty() const;
152 :
153 : bool isDeltaApplicable() const;
154 :
155 : bool apply(const Value &query);
156 : void resolve(const Vector<StringView> &);
157 :
158 : uint16_t getResolveDepth() const;
159 : void setResolveDepth(uint16_t);
160 :
161 : void setDelta(stappler::Time);
162 : stappler::Time getDelta() const;
163 :
164 : size_t size() const;
165 :
166 : const Scheme *getPrimaryScheme() const;
167 : const Scheme *getSourceScheme() const;
168 : const Scheme *getScheme() const;
169 : const Field *getField() const;
170 : const Query &getTopQuery() const;
171 :
172 : const Vector<Item> &getItems() const;
173 :
174 : const Query::FieldsVec &getIncludeFields() const;
175 : const Query::FieldsVec &getExcludeFields() const;
176 :
177 : QueryFieldResolver getFields() const;
178 :
179 : const Value &getExtraData() const;
180 : ContinueToken &getContinueToken() const;
181 :
182 0 : const ApplicationInterface *getApplicationInterface() const { return _application; }
183 :
184 : protected:
185 : void decodeSelect(const Scheme &, Query &, const Value &);
186 : void decodeOrder(const Scheme &, Query &, const String &, const Value &);
187 :
188 : const ApplicationInterface *_application = nullptr;
189 : Flags _flags = Flags::None;
190 : Vector<Item> queries;
191 : Value extraData;
192 : mutable ContinueToken token;
193 : bool failed = false;
194 : };
195 :
196 : SP_DEFINE_ENUM_AS_MASK(QueryList::Flags);
197 :
198 : }
199 :
200 : #endif /* STAPPLER_DB_SPDBQUERYLIST_H_ */
|