Skip to content

Commit cd23c32

Browse files
authored
Add support for min/max query. (#18314)
1 parent 82f4f67 commit cd23c32

1 file changed

Lines changed: 78 additions & 0 deletions

File tree

libretro-db/query.c

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ struct registered_func
9090
rarch_query_func func;
9191
};
9292

93+
struct rmsgpack_dom_value intermediate_res;
94+
9395
/* Forward declarations */
9496
static struct buffer query_parse_method_call(char *s, size_t len,
9597
struct buffer buff, struct invocation *invocation, const char **err);
@@ -254,12 +256,85 @@ static struct rmsgpack_dom_value query_func_glob(
254256
return res;
255257
}
256258

259+
/* Min and max functions will return all entries smaller/larger than previous *
260+
* - in practice, last entry will contain the actual min/max value. *
261+
* Empty result means there is no such field. */
262+
static struct rmsgpack_dom_value query_func_min(
263+
struct rmsgpack_dom_value input,
264+
unsigned argc, const struct argument * argv)
265+
{
266+
struct rmsgpack_dom_value res;
267+
268+
res.type = RDT_BOOL;
269+
res.val.bool_ = 0;
270+
271+
switch (input.type)
272+
{
273+
case RDT_INT:
274+
res.val.bool_ = (
275+
(input.val.int_ == 0)
276+
|| (input.val.int_ < intermediate_res.val.int_)
277+
|| (intermediate_res.val.int_ == 0));
278+
if (res.val.bool_ || intermediate_res.val.int_ == 0)
279+
memcpy(&intermediate_res, &input, sizeof(intermediate_res));
280+
break;
281+
case RDT_UINT:
282+
res.val.bool_ = (
283+
(input.val.uint_ == 0)
284+
|| (input.val.uint_ < intermediate_res.val.uint_)
285+
|| (intermediate_res.val.uint_ == 0));
286+
if (res.val.bool_ || intermediate_res.val.uint_ == 0)
287+
memcpy(&intermediate_res, &input, sizeof(intermediate_res));
288+
break;
289+
default:
290+
break;
291+
}
292+
293+
return res;
294+
}
295+
296+
static struct rmsgpack_dom_value query_func_max(
297+
struct rmsgpack_dom_value input,
298+
unsigned argc, const struct argument * argv)
299+
{
300+
struct rmsgpack_dom_value res;
301+
302+
res.type = RDT_BOOL;
303+
res.val.bool_ = 0;
304+
305+
switch (input.type)
306+
{
307+
case RDT_INT:
308+
res.val.bool_ = (
309+
(input.val.int_ == 0)
310+
|| (input.val.int_ > intermediate_res.val.int_)
311+
|| (intermediate_res.val.int_ == 0));
312+
if (res.val.bool_ || intermediate_res.val.int_ == 0)
313+
memcpy(&intermediate_res, &input, sizeof(intermediate_res));
314+
break;
315+
case RDT_UINT:
316+
res.val.bool_ = (
317+
(input.val.uint_ == 0)
318+
|| (input.val.uint_ > intermediate_res.val.uint_)
319+
|| (intermediate_res.val.uint_ == 0));
320+
if (res.val.bool_ || intermediate_res.val.uint_ == 0)
321+
memcpy(&intermediate_res, &input, sizeof(intermediate_res));
322+
break;
323+
default:
324+
break;
325+
}
326+
327+
return res;
328+
}
329+
257330
struct registered_func registered_functions[100] = {
258331
{"is_true", query_func_is_true},
259332
{"or", query_func_operator_or},
260333
{"and", query_func_operator_and},
261334
{"between", query_func_between},
262335
{"glob", query_func_glob},
336+
{"min", query_func_min},
337+
{"max", query_func_max},
263338
{NULL, NULL}
264339
};
265340

@@ -905,6 +980,9 @@ void *libretrodb_query_compile(libretrodb_t *db,
905980
struct query *q = (struct query*)malloc(sizeof(*q));
906981
size_t err_buff_len = sizeof(tmp_err_buff);
907982

983+
intermediate_res.val.int_ = 0;
984+
intermediate_res.val.uint_ = 0;
985+
908986
if (!q)
909987
return NULL;
910988

0 commit comments

Comments
 (0)