added iOS source code
[wl-app.git] / iOS / Pods / Realm / include / core / realm / query.hpp
1 /*************************************************************************
2  *
3  * Copyright 2016 Realm Inc.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  **************************************************************************/
18
19 #ifndef REALM_QUERY_HPP
20 #define REALM_QUERY_HPP
21
22 #include <cstdint>
23 #include <cstdio>
24 #include <climits>
25 #include <algorithm>
26 #include <string>
27 #include <vector>
28
29 #define REALM_MULTITHREAD_QUERY 0
30
31 #if REALM_MULTITHREAD_QUERY
32 // FIXME: Use our C++ thread abstraction API since it provides a much
33 // higher level of encapsulation and safety.
34 #include <pthread.h>
35 #endif
36
37 #include <realm/views.hpp>
38 #include <realm/table_ref.hpp>
39 #include <realm/binary_data.hpp>
40 #include <realm/olddatetime.hpp>
41 #include <realm/handover_defs.hpp>
42 #include <realm/link_view_fwd.hpp>
43 #include <realm/descriptor_fwd.hpp>
44 #include <realm/row.hpp>
45
46 namespace realm {
47
48
49 // Pre-declarations
50 class ParentNode;
51 class Table;
52 class TableView;
53 class TableViewBase;
54 class ConstTableView;
55 class Array;
56 class Expression;
57 class SequentialGetterBase;
58 class Group;
59
60 namespace metrics {
61 class QueryInfo;
62 }
63
64 struct QueryGroup {
65     enum class State {
66         Default,
67         OrCondition,
68         OrConditionChildren,
69     };
70
71     QueryGroup() = default;
72
73     QueryGroup(const QueryGroup&);
74     QueryGroup& operator=(const QueryGroup&);
75
76     QueryGroup(QueryGroup&&) = default;
77     QueryGroup& operator=(QueryGroup&&) = default;
78
79     QueryGroup(const QueryGroup&, QueryNodeHandoverPatches&);
80
81     std::unique_ptr<ParentNode> m_root_node;
82
83     bool m_pending_not = false;
84     size_t m_subtable_column = not_found;
85     State m_state = State::Default;
86 };
87
88 class Query final {
89 public:
90     Query(const Table& table, TableViewBase* tv = nullptr);
91     Query(const Table& table, std::unique_ptr<TableViewBase>);
92     Query(const Table& table, const LinkViewRef& lv);
93     Query();
94     Query(std::unique_ptr<Expression>);
95     ~Query() noexcept;
96
97     Query(const Query& copy);
98     Query& operator=(const Query& source);
99
100     Query(Query&&);
101     Query& operator=(Query&&);
102
103     // Find links that point to a specific target row
104     Query& links_to(size_t column_ndx, const ConstRow& target_row);
105
106     // Conditions: null
107     Query& equal(size_t column_ndx, null);
108     Query& not_equal(size_t column_ndx, null);
109
110     // Conditions: int64_t
111     Query& equal(size_t column_ndx, int64_t value);
112     Query& not_equal(size_t column_ndx, int64_t value);
113     Query& greater(size_t column_ndx, int64_t value);
114     Query& greater_equal(size_t column_ndx, int64_t value);
115     Query& less(size_t column_ndx, int64_t value);
116     Query& less_equal(size_t column_ndx, int64_t value);
117     Query& between(size_t column_ndx, int64_t from, int64_t to);
118
119     // Conditions: int (we need those because conversion from '1234' is ambiguous with float/double)
120     Query& equal(size_t column_ndx, int value);
121     Query& not_equal(size_t column_ndx, int value);
122     Query& greater(size_t column_ndx, int value);
123     Query& greater_equal(size_t column_ndx, int value);
124     Query& less(size_t column_ndx, int value);
125     Query& less_equal(size_t column_ndx, int value);
126     Query& between(size_t column_ndx, int from, int to);
127
128     // Conditions: 2 int columns
129     Query& equal_int(size_t column_ndx1, size_t column_ndx2);
130     Query& not_equal_int(size_t column_ndx1, size_t column_ndx2);
131     Query& greater_int(size_t column_ndx1, size_t column_ndx2);
132     Query& less_int(size_t column_ndx1, size_t column_ndx2);
133     Query& greater_equal_int(size_t column_ndx1, size_t column_ndx2);
134     Query& less_equal_int(size_t column_ndx1, size_t column_ndx2);
135
136     // Conditions: float
137     Query& equal(size_t column_ndx, float value);
138     Query& not_equal(size_t column_ndx, float value);
139     Query& greater(size_t column_ndx, float value);
140     Query& greater_equal(size_t column_ndx, float value);
141     Query& less(size_t column_ndx, float value);
142     Query& less_equal(size_t column_ndx, float value);
143     Query& between(size_t column_ndx, float from, float to);
144
145     // Conditions: 2 float columns
146     Query& equal_float(size_t column_ndx1, size_t column_ndx2);
147     Query& not_equal_float(size_t column_ndx1, size_t column_ndx2);
148     Query& greater_float(size_t column_ndx1, size_t column_ndx2);
149     Query& greater_equal_float(size_t column_ndx1, size_t column_ndx2);
150     Query& less_float(size_t column_ndx1, size_t column_ndx2);
151     Query& less_equal_float(size_t column_ndx1, size_t column_ndx2);
152
153     // Conditions: double
154     Query& equal(size_t column_ndx, double value);
155     Query& not_equal(size_t column_ndx, double value);
156     Query& greater(size_t column_ndx, double value);
157     Query& greater_equal(size_t column_ndx, double value);
158     Query& less(size_t column_ndx, double value);
159     Query& less_equal(size_t column_ndx, double value);
160     Query& between(size_t column_ndx, double from, double to);
161
162     // Conditions: 2 double columns
163     Query& equal_double(size_t column_ndx1, size_t column_ndx2);
164     Query& not_equal_double(size_t column_ndx1, size_t column_ndx2);
165     Query& greater_double(size_t column_ndx1, size_t column_ndx2);
166     Query& greater_equal_double(size_t column_ndx1, size_t column_ndx2);
167     Query& less_double(size_t column_ndx1, size_t column_ndx2);
168     Query& less_equal_double(size_t column_ndx1, size_t column_ndx2);
169
170     // Conditions: timestamp
171     Query& equal(size_t column_ndx, Timestamp value);
172     Query& not_equal(size_t column_ndx, Timestamp value);
173     Query& greater(size_t column_ndx, Timestamp value);
174     Query& greater_equal(size_t column_ndx, Timestamp value);
175     Query& less_equal(size_t column_ndx, Timestamp value);
176     Query& less(size_t column_ndx, Timestamp value);
177
178     // Conditions: size
179     Query& size_equal(size_t column_ndx, int64_t value);
180     Query& size_not_equal(size_t column_ndx, int64_t value);
181     Query& size_greater(size_t column_ndx, int64_t value);
182     Query& size_greater_equal(size_t column_ndx, int64_t value);
183     Query& size_less_equal(size_t column_ndx, int64_t value);
184     Query& size_less(size_t column_ndx, int64_t value);
185     Query& size_between(size_t column_ndx, int64_t from, int64_t to);
186
187     // Conditions: bool
188     Query& equal(size_t column_ndx, bool value);
189
190     // Conditions: date
191     Query& equal_olddatetime(size_t column_ndx, OldDateTime value)
192     {
193         return equal(column_ndx, int64_t(value.get_olddatetime()));
194     }
195     Query& not_equal_olddatetime(size_t column_ndx, OldDateTime value)
196     {
197         return not_equal(column_ndx, int64_t(value.get_olddatetime()));
198     }
199     Query& greater_olddatetime(size_t column_ndx, OldDateTime value)
200     {
201         return greater(column_ndx, int64_t(value.get_olddatetime()));
202     }
203     Query& greater_equal_olddatetime(size_t column_ndx, OldDateTime value)
204     {
205         return greater_equal(column_ndx, int64_t(value.get_olddatetime()));
206     }
207     Query& less_olddatetime(size_t column_ndx, OldDateTime value)
208     {
209         return less(column_ndx, int64_t(value.get_olddatetime()));
210     }
211     Query& less_equal_olddatetime(size_t column_ndx, OldDateTime value)
212     {
213         return less_equal(column_ndx, int64_t(value.get_olddatetime()));
214     }
215     Query& between_olddatetime(size_t column_ndx, OldDateTime from, OldDateTime to)
216     {
217         return between(column_ndx, int64_t(from.get_olddatetime()), int64_t(to.get_olddatetime()));
218     }
219
220     // Conditions: strings
221     Query& equal(size_t column_ndx, StringData value, bool case_sensitive = true);
222     Query& not_equal(size_t column_ndx, StringData value, bool case_sensitive = true);
223     Query& begins_with(size_t column_ndx, StringData value, bool case_sensitive = true);
224     Query& ends_with(size_t column_ndx, StringData value, bool case_sensitive = true);
225     Query& contains(size_t column_ndx, StringData value, bool case_sensitive = true);
226     Query& like(size_t column_ndx, StringData value, bool case_sensitive = true);
227
228     // These are shortcuts for equal(StringData(c_str)) and
229     // not_equal(StringData(c_str)), and are needed to avoid unwanted
230     // implicit conversion of char* to bool.
231     Query& equal(size_t column_ndx, const char* c_str, bool case_sensitive = true);
232     Query& not_equal(size_t column_ndx, const char* c_str, bool case_sensitive = true);
233
234     // Conditions: binary data
235     Query& equal(size_t column_ndx, BinaryData value);
236     Query& not_equal(size_t column_ndx, BinaryData value);
237     Query& begins_with(size_t column_ndx, BinaryData value);
238     Query& ends_with(size_t column_ndx, BinaryData value);
239     Query& contains(size_t column_ndx, BinaryData value);
240
241     // Negation
242     Query& Not();
243
244     // Grouping
245     Query& group();
246     Query& end_group();
247     Query& subtable(size_t column);
248     Query& end_subtable();
249     Query& Or();
250
251     Query& and_query(const Query& q);
252     Query& and_query(Query&& q);
253     Query operator||(const Query& q);
254     Query operator&&(const Query& q);
255     Query operator!();
256
257
258     // Searching
259     size_t find(size_t begin_at_table_row = size_t(0));
260     TableView find_all(size_t start = 0, size_t end = size_t(-1), size_t limit = size_t(-1));
261     ConstTableView find_all(size_t start = 0, size_t end = size_t(-1), size_t limit = size_t(-1)) const;
262
263     // Aggregates
264     size_t count(size_t start = 0, size_t end = size_t(-1), size_t limit = size_t(-1)) const;
265
266     int64_t sum_int(size_t column_ndx, size_t* resultcount = nullptr, size_t start = 0, size_t end = size_t(-1),
267                     size_t limit = size_t(-1)) const;
268
269     double average_int(size_t column_ndx, size_t* resultcount = nullptr, size_t start = 0, size_t end = size_t(-1),
270                        size_t limit = size_t(-1)) const;
271
272     int64_t maximum_int(size_t column_ndx, size_t* resultcount = nullptr, size_t start = 0, size_t end = size_t(-1),
273                         size_t limit = size_t(-1), size_t* return_ndx = nullptr) const;
274
275     int64_t minimum_int(size_t column_ndx, size_t* resultcount = nullptr, size_t start = 0, size_t end = size_t(-1),
276                         size_t limit = size_t(-1), size_t* return_ndx = nullptr) const;
277
278     double sum_float(size_t column_ndx, size_t* resultcount = nullptr, size_t start = 0, size_t end = size_t(-1),
279                      size_t limit = size_t(-1)) const;
280
281     double average_float(size_t column_ndx, size_t* resultcount = nullptr, size_t start = 0, size_t end = size_t(-1),
282                          size_t limit = size_t(-1)) const;
283
284     float maximum_float(size_t column_ndx, size_t* resultcount = nullptr, size_t start = 0, size_t end = size_t(-1),
285                         size_t limit = size_t(-1), size_t* return_ndx = nullptr) const;
286
287     float minimum_float(size_t column_ndx, size_t* resultcount = nullptr, size_t start = 0, size_t end = size_t(-1),
288                         size_t limit = size_t(-1), size_t* return_ndx = nullptr) const;
289
290     double sum_double(size_t column_ndx, size_t* resultcount = nullptr, size_t start = 0, size_t end = size_t(-1),
291                       size_t limit = size_t(-1)) const;
292
293     double average_double(size_t column_ndx, size_t* resultcount = nullptr, size_t start = 0, size_t end = size_t(-1),
294                           size_t limit = size_t(-1)) const;
295
296     double maximum_double(size_t column_ndx, size_t* resultcount = nullptr, size_t start = 0, size_t end = size_t(-1),
297                           size_t limit = size_t(-1), size_t* return_ndx = nullptr) const;
298
299     double minimum_double(size_t column_ndx, size_t* resultcount = nullptr, size_t start = 0, size_t end = size_t(-1),
300                           size_t limit = size_t(-1), size_t* return_ndx = nullptr) const;
301
302     OldDateTime maximum_olddatetime(size_t column_ndx, size_t* resultcount = nullptr, size_t start = 0,
303                                     size_t end = size_t(-1), size_t limit = size_t(-1),
304                                     size_t* return_ndx = nullptr) const;
305
306     OldDateTime minimum_olddatetime(size_t column_ndx, size_t* resultcount = nullptr, size_t start = 0,
307                                     size_t end = size_t(-1), size_t limit = size_t(-1),
308                                     size_t* return_ndx = nullptr) const;
309
310     Timestamp maximum_timestamp(size_t column_ndx, size_t* return_ndx, size_t start = 0, size_t end = size_t(-1),
311                                 size_t limit = size_t(-1));
312
313     Timestamp minimum_timestamp(size_t column_ndx, size_t* return_ndx, size_t start = 0, size_t end = size_t(-1),
314                                 size_t limit = size_t(-1));
315
316     // Deletion
317     size_t remove();
318
319 #if REALM_MULTITHREAD_QUERY
320     // Multi-threading
321     TableView find_all_multi(size_t start = 0, size_t end = size_t(-1));
322     ConstTableView find_all_multi(size_t start = 0, size_t end = size_t(-1)) const;
323     int set_threads(unsigned int threadcount);
324 #endif
325
326     const TableRef& get_table()
327     {
328         return m_table;
329     }
330
331     // True if matching rows are guaranteed to be returned in table order.
332     bool produces_results_in_table_order() const
333     {
334         return !m_view;
335     }
336
337     // Calls sync_if_needed on the restricting view, if present.
338     // Returns the current version of the table(s) this query depends on,
339     // or util::none if the query is not associated with a table.
340     util::Optional<uint_fast64_t> sync_view_if_needed() const;
341
342     std::string validate();
343
344     std::string get_description() const;
345
346 private:
347     Query(Table& table, TableViewBase* tv = nullptr);
348     void create();
349
350     void init() const;
351     size_t find_internal(size_t start = 0, size_t end = size_t(-1)) const;
352     size_t peek_tablerow(size_t row) const;
353     void handle_pending_not();
354     void set_table(TableRef tr);
355
356 public:
357     using HandoverPatch = QueryHandoverPatch;
358
359     std::unique_ptr<Query> clone_for_handover(std::unique_ptr<HandoverPatch>& patch, ConstSourcePayload mode) const
360     {
361         patch.reset(new HandoverPatch);
362         return std::make_unique<Query>(*this, *patch, mode);
363     }
364
365     std::unique_ptr<Query> clone_for_handover(std::unique_ptr<HandoverPatch>& patch, MutableSourcePayload mode)
366     {
367         patch.reset(new HandoverPatch);
368         return std::make_unique<Query>(*this, *patch, mode);
369     }
370
371     void apply_and_consume_patch(std::unique_ptr<HandoverPatch>& patch, Group& dest_group)
372     {
373         apply_patch(*patch, dest_group);
374         patch.reset();
375     }
376
377     void apply_patch(HandoverPatch& patch, Group& dest_group);
378     Query(const Query& source, HandoverPatch& patch, ConstSourcePayload mode);
379     Query(Query& source, HandoverPatch& patch, MutableSourcePayload mode);
380
381 private:
382     void fetch_descriptor();
383
384     void add_expression_node(std::unique_ptr<Expression>);
385
386     template <class ColumnType>
387     Query& equal(size_t column_ndx1, size_t column_ndx2);
388
389     template <class ColumnType>
390     Query& less(size_t column_ndx1, size_t column_ndx2);
391
392     template <class ColumnType>
393     Query& less_equal(size_t column_ndx1, size_t column_ndx2);
394
395     template <class ColumnType>
396     Query& greater(size_t column_ndx1, size_t column_ndx2);
397
398     template <class ColumnType>
399     Query& greater_equal(size_t column_ndx1, size_t column_ndx2);
400
401     template <class ColumnType>
402     Query& not_equal(size_t column_ndx1, size_t column_ndx2);
403
404     template <typename TConditionFunction, class T>
405     Query& add_condition(size_t column_ndx, T value);
406
407     template <typename TConditionFunction>
408     Query& add_size_condition(size_t column_ndx, int64_t value);
409
410     template <typename T, bool Nullable>
411     double average(size_t column_ndx, size_t* resultcount = nullptr, size_t start = 0, size_t end = size_t(-1),
412                    size_t limit = size_t(-1)) const;
413
414     template <Action action, typename T, typename R, class ColClass>
415     R aggregate(R (ColClass::*method)(size_t, size_t, size_t, size_t*) const, size_t column_ndx, size_t* resultcount,
416                 size_t start, size_t end, size_t limit, size_t* return_ndx = nullptr) const;
417
418     void aggregate_internal(Action TAction, DataType TSourceColumn, bool nullable, ParentNode* pn, QueryStateBase* st,
419                             size_t start, size_t end, SequentialGetterBase* source_column) const;
420
421     void find_all(TableViewBase& tv, size_t start = 0, size_t end = size_t(-1), size_t limit = size_t(-1)) const;
422     void delete_nodes() noexcept;
423
424     bool has_conditions() const
425     {
426         return m_groups.size() > 0 && m_groups[0].m_root_node;
427     }
428     ParentNode* root_node() const
429     {
430         REALM_ASSERT(m_groups.size());
431         return m_groups[0].m_root_node.get();
432     }
433
434     void add_node(std::unique_ptr<ParentNode>);
435
436     friend class Table;
437     friend class TableViewBase;
438     friend class metrics::QueryInfo;
439
440     std::string error_code;
441
442     std::vector<QueryGroup> m_groups;
443
444     // Used to access schema while building query:
445     std::vector<size_t> m_subtable_path;
446
447     ConstDescriptorRef m_current_descriptor;
448     TableRef m_table;
449
450     // points to the base class of the restricting view. If the restricting
451     // view is a link view, m_source_link_view is non-zero. If it is a table view,
452     // m_source_table_view is non-zero.
453     RowIndexes* m_view = nullptr;
454
455     // At most one of these can be non-zero, and if so the non-zero one indicates the restricting view.
456     LinkViewRef m_source_link_view;               // link views are refcounted and shared.
457     TableViewBase* m_source_table_view = nullptr; // table views are not refcounted, and not owned by the query.
458     std::unique_ptr<TableViewBase> m_owned_source_table_view; // <--- except when indicated here
459 };
460
461 // Implementation:
462
463 inline Query& Query::equal(size_t column_ndx, const char* c_str, bool case_sensitive)
464 {
465     return equal(column_ndx, StringData(c_str), case_sensitive);
466 }
467
468 inline Query& Query::not_equal(size_t column_ndx, const char* c_str, bool case_sensitive)
469 {
470     return not_equal(column_ndx, StringData(c_str), case_sensitive);
471 }
472
473 } // namespace realm
474
475 #endif // REALM_QUERY_HPP