• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

realm / realm-core / 1682

18 Sep 2023 05:17PM UTC coverage: 91.23% (+0.04%) from 91.19%
1682

push

Evergreen

web-flow
Merge pull request #6886 from realm/blagoev/custom-v13.17.1

fix ErrorStorage creation

96020 of 175988 branches covered (0.0%)

0 of 2 new or added lines in 1 file covered. (0.0%)

71 existing lines in 7 files now uncovered.

233857 of 256337 relevant lines covered (91.23%)

6774909.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

69.19
/src/realm/parser/query_parser.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_PARSER_QUERY_PARSER_HPP
20
#define REALM_PARSER_QUERY_PARSER_HPP
21

22
#include <realm/string_data.hpp>
23
#include <realm/binary_data.hpp>
24
#include <realm/timestamp.hpp>
25
#include <realm/keys.hpp>
26
#include <realm/object_id.hpp>
27
#include <realm/decimal128.hpp>
28
#include <realm/uuid.hpp>
29
#include <realm/util/any.hpp>
30
#include <realm/mixed.hpp>
31

32
namespace realm::query_parser {
33

34
struct AnyContext {
35
    template <typename T>
36
    T unbox(const std::any& wrapper)
37
    {
1,484✔
38
        return util::any_cast<T>(wrapper);
1,484✔
39
    }
1,484✔
40
    bool is_null(const std::any& wrapper)
41
    {
1,590✔
42
        if (!wrapper.has_value()) {
1,590✔
43
            return true;
48✔
44
        }
48✔
45
        if (wrapper.type() == typeid(realm::null)) {
1,542✔
46
            return true;
58✔
47
        }
58✔
48
        return false;
1,484✔
49
    }
1,484✔
50
    bool is_list(const std::any& wrapper)
51
    {
1,496✔
52
        if (!wrapper.has_value()) {
1,496✔
53
            return false;
×
54
        }
×
55
        if (wrapper.type() == typeid(std::vector<Mixed>)) {
1,496✔
56
            return true;
20✔
57
        }
20✔
58
        return false;
1,476✔
59
    }
1,476✔
60
    DataType get_type_of(const std::any& wrapper)
61
    {
1,470✔
62
        const std::type_info& type{wrapper.type()};
1,470✔
63
        if (type == typeid(int64_t)) {
1,470✔
64
            return type_Int;
176✔
65
        }
176✔
66
        if (type == typeid(StringData)) {
1,294✔
67
            return type_String;
86✔
68
        }
86✔
69
        if (type == typeid(Timestamp)) {
1,208✔
70
            return type_Timestamp;
146✔
71
        }
146✔
72
        if (type == typeid(double)) {
1,062✔
73
            return type_Double;
168✔
74
        }
168✔
75
        if (type == typeid(bool)) {
894✔
76
            return type_Bool;
108✔
77
        }
108✔
78
        if (type == typeid(float)) {
786✔
79
            return type_Float;
168✔
80
        }
168✔
81
        if (type == typeid(BinaryData)) {
618✔
82
            return type_Binary;
84✔
83
        }
84✔
84
        if (type == typeid(ObjKey)) {
534✔
85
            return type_Link;
2✔
86
        }
2✔
87
        if (type == typeid(ObjectId)) {
532✔
88
            return type_ObjectId;
212✔
89
        }
212✔
90
        if (type == typeid(Decimal128)) {
320✔
91
            return type_Decimal;
156✔
92
        }
156✔
93
        if (type == typeid(UUID)) {
164✔
94
            return type_UUID;
144✔
95
        }
144✔
96
        if (type == typeid(ObjLink)) {
20✔
97
            return type_TypedLink;
20✔
98
        }
20✔
UNCOV
99
        if (type == typeid(Mixed)) {
×
100
            return type_Mixed;
×
101
        }
×
UNCOV
102
        return DataType(-1);
×
UNCOV
103
    }
×
104
};
105

106
class Arguments {
107
public:
108
    Arguments(size_t num_args)
109
        : m_count(num_args)
110
    {
27,472✔
111
    }
27,472✔
112
    virtual ~Arguments() = default;
27,466✔
113
    virtual bool bool_for_argument(size_t argument_index) = 0;
114
    virtual long long long_for_argument(size_t argument_index) = 0;
115
    virtual float float_for_argument(size_t argument_index) = 0;
116
    virtual double double_for_argument(size_t argument_index) = 0;
117
    virtual StringData string_for_argument(size_t argument_index) = 0;
118
    virtual BinaryData binary_for_argument(size_t argument_index) = 0;
119
    virtual Timestamp timestamp_for_argument(size_t argument_index) = 0;
120
    virtual ObjKey object_index_for_argument(size_t argument_index) = 0;
121
    virtual ObjectId objectid_for_argument(size_t argument_index) = 0;
122
    virtual Decimal128 decimal128_for_argument(size_t argument_index) = 0;
123
    virtual UUID uuid_for_argument(size_t argument_index) = 0;
124
    virtual ObjLink objlink_for_argument(size_t argument_index) = 0;
125
#if REALM_ENABLE_GEOSPATIAL
126
    virtual Geospatial geospatial_for_argument(size_t argument_index) = 0;
127
#endif
128
    virtual std::vector<Mixed> list_for_argument(size_t argument_index) = 0;
129
    virtual bool is_argument_null(size_t argument_index) = 0;
130
    virtual bool is_argument_list(size_t argument_index) = 0;
131
    virtual DataType type_for_argument(size_t argument_index) = 0;
132
    size_t get_num_args() const
133
    {
×
134
        return m_count;
×
135
    }
×
136
protected:
137
    void verify_ndx(size_t ndx) const
138
    {
2,586,048✔
139
        if (ndx >= m_count) {
2,586,048✔
140
            std::string error_message;
28✔
141
            if (m_count) {
28✔
142
                error_message = util::format("Request for argument at index %1 but only %2 argument%3 provided", ndx,
16✔
143
                                             m_count, m_count == 1 ? " is" : "s are");
12✔
144
            }
16✔
145
            else {
12✔
146
                error_message = util::format("Request for argument at index %1 but no arguments are provided", ndx);
12✔
147
            }
12✔
148
            throw InvalidArgument(ErrorCodes::OutOfBounds, error_message);
28✔
149
        }
28✔
150
    }
2,586,048✔
151
    size_t m_count;
152
};
153

154

155
template <typename ValueType, typename ContextType>
156
class ArgumentConverter : public Arguments {
157
public:
158
    ArgumentConverter(ContextType& context, const ValueType* arguments, size_t count)
159
        : Arguments(count)
160
        , m_ctx(context)
161
        , m_arguments(arguments)
162
    {
1,602✔
163
    }
1,602✔
164

165
    bool bool_for_argument(size_t i) override
166
    {
108✔
167
        return get<bool>(i);
108✔
168
    }
108✔
169
    long long long_for_argument(size_t i) override
170
    {
176✔
171
        return get<int64_t>(i);
176✔
172
    }
176✔
173
    float float_for_argument(size_t i) override
174
    {
168✔
175
        return get<float>(i);
168✔
176
    }
168✔
177
    double double_for_argument(size_t i) override
178
    {
168✔
179
        return get<double>(i);
168✔
180
    }
168✔
181
    StringData string_for_argument(size_t i) override
182
    {
86✔
183
        return get<StringData>(i);
86✔
184
    }
86✔
185
    BinaryData binary_for_argument(size_t i) override
186
    {
84✔
187
        return get<BinaryData>(i);
84✔
188
    }
84✔
189
    Timestamp timestamp_for_argument(size_t i) override
190
    {
146✔
191
        return get<Timestamp>(i);
146✔
192
    }
146✔
193
    ObjectId objectid_for_argument(size_t i) override
194
    {
212✔
195
        return get<ObjectId>(i);
212✔
196
    }
212✔
197
    UUID uuid_for_argument(size_t i) override
198
    {
144✔
199
        return get<UUID>(i);
144✔
200
    }
144✔
201
    Decimal128 decimal128_for_argument(size_t i) override
202
    {
156✔
203
        return get<Decimal128>(i);
156✔
204
    }
156✔
205
    ObjKey object_index_for_argument(size_t i) override
206
    {
2✔
207
        return get<ObjKey>(i);
2✔
208
    }
2✔
209
    ObjLink objlink_for_argument(size_t i) override
210
    {
20✔
211
        return get<ObjLink>(i);
20✔
212
    }
20✔
213
#if REALM_ENABLE_GEOSPATIAL
214
    Geospatial geospatial_for_argument(size_t i) override
215
    {
×
216
        return get<Geospatial>(i);
×
217
    }
×
218
#endif
219
    std::vector<Mixed> list_for_argument(size_t i) override
220
    {
14✔
221
        return get<std::vector<Mixed>>(i);
14✔
222
    }
14✔
223
    bool is_argument_list(size_t i) override
224
    {
1,496✔
225
        return m_ctx.is_list(at(i));
1,496✔
226
    }
1,496✔
227
    bool is_argument_null(size_t i) override
228
    {
1,596✔
229
        return m_ctx.is_null(at(i));
1,596✔
230
    }
1,596✔
231

232
private:
233
    ContextType& m_ctx;
234
    const ValueType* m_arguments;
235

236
    const ValueType& at(size_t index) const
237
    {
6,046✔
238
        Arguments::verify_ndx(index);
6,046✔
239
        return m_arguments[index];
6,046✔
240
    }
6,046✔
241

242
    DataType type_for_argument(size_t i) override
243
    {
1,470✔
244
        return m_ctx.get_type_of(at(i));
1,470✔
245
    }
1,470✔
246

247
    template <typename T>
248
    T get(size_t index) const
249
    {
1,484✔
250
        return m_ctx.template unbox<T>(at(index));
1,484✔
251
    }
1,484✔
252
};
253

254
class NoArgsError : public InvalidQueryArgError {
255
public:
256
    NoArgsError()
257
        : InvalidQueryArgError("Attempt to retreive an argument when no arguments were given")
258
    {
4✔
259
    }
4✔
260
};
261

262
class NoArguments : public Arguments {
263
public:
264
    NoArguments()
265
        : Arguments(0)
266
    {
10,544✔
267
    }
10,544✔
268
    bool bool_for_argument(size_t)
269
    {
×
270
        throw NoArgsError();
×
271
    }
×
272
    long long long_for_argument(size_t)
273
    {
×
274
        throw NoArgsError();
×
275
    }
×
276
    float float_for_argument(size_t)
277
    {
×
278
        throw NoArgsError();
×
279
    }
×
280
    double double_for_argument(size_t)
281
    {
×
282
        throw NoArgsError();
×
283
    }
×
284
    StringData string_for_argument(size_t)
285
    {
×
286
        throw NoArgsError();
×
287
    }
×
288
    BinaryData binary_for_argument(size_t)
289
    {
×
290
        throw NoArgsError();
×
291
    }
×
292
    Timestamp timestamp_for_argument(size_t)
293
    {
×
294
        throw NoArgsError();
×
295
    }
×
296
    ObjectId objectid_for_argument(size_t)
297
    {
×
298
        throw NoArgsError();
×
299
    }
×
300
    Decimal128 decimal128_for_argument(size_t)
301
    {
×
302
        throw NoArgsError();
×
303
    }
×
304
    UUID uuid_for_argument(size_t)
305
    {
×
306
        throw NoArgsError();
×
307
    }
×
308
    ObjKey object_index_for_argument(size_t)
309
    {
×
310
        throw NoArgsError();
×
311
    }
×
312
    ObjLink objlink_for_argument(size_t)
313
    {
×
314
        throw NoArgsError();
×
315
    }
×
316
#if REALM_ENABLE_GEOSPATIAL
317
    Geospatial geospatial_for_argument(size_t)
318
    {
×
319
        throw NoArgsError();
×
320
    }
×
321
#endif
322
    bool is_argument_list(size_t)
323
    {
×
324
        throw NoArgsError();
×
325
    }
×
326
    std::vector<Mixed> list_for_argument(size_t)
327
    {
×
328
        throw NoArgsError();
×
329
    }
×
330
    bool is_argument_null(size_t)
331
    {
4✔
332
        throw NoArgsError();
4✔
333
    }
4✔
334
    DataType type_for_argument(size_t)
335
    {
×
336
        throw NoArgsError();
×
337
    }
×
338
};
339

340
void parse(const std::string&);
341

342
} // namespace realm::query_parser
343

344

345
#endif /* REALM_PARSER_QUERY_PARSER_HPP */
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc