Skip to content

Commit c69265d

Browse files
authored
Merge pull request #1435 from fnc12/ast-refactoring
Ast refactoring
2 parents 7f929f9 + 339c95b commit c69265d

File tree

10 files changed

+243
-152
lines changed

10 files changed

+243
-152
lines changed

dev/ast/limit.h

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#pragma once
2+
3+
#ifndef SQLITE_ORM_IMPORT_STD_MODULE
4+
#include <utility> // std::move
5+
#include <type_traits> // std::true_type, std::false_type
6+
#endif // SQLITE_ORM_IMPORT_STD_MODULE
7+
8+
#include "../optional_container.h"
9+
#include "../type_traits.h"
10+
#include "offset.h"
11+
12+
namespace sqlite_orm {
13+
14+
namespace internal {
15+
/**
16+
* Stores LIMIT/OFFSET info
17+
*/
18+
template<class T, bool has_offset, bool offset_is_implicit, class O>
19+
struct limit_t {
20+
T limit;
21+
optional_container<O> offset;
22+
};
23+
24+
template<class T>
25+
struct is_limit : std::false_type {};
26+
27+
template<class T, bool has_offset, bool offset_is_implicit, class O>
28+
struct is_limit<limit_t<T, has_offset, offset_is_implicit, O>> : std::true_type {};
29+
}
30+
31+
/**
32+
* LIMIT clause.
33+
* Example: limit(10)
34+
* @param limit The maximum number of rows to return.
35+
* @return limit_t instance representing LIMIT clause.
36+
*/
37+
template<class T>
38+
internal::limit_t<T, false, false, void> limit(T limit) {
39+
return {std::move(limit)};
40+
}
41+
42+
/**
43+
* LIMIT with OFFSET clause (implicit offset).
44+
* Example: limit(5, 10) // OFFSET 5 LIMIT 10
45+
* @param offset The offset value (number of rows to skip).
46+
* @param limit The limit value (maximum number of rows to return).
47+
* @return limit_t instance representing LIMIT and OFFSET clause.
48+
*/
49+
template<class T, class O, internal::satisfies_not<internal::is_offset, T> = true>
50+
internal::limit_t<T, true, true, O> limit(O offset, T limit) {
51+
return {std::move(limit), {std::move(offset)}};
52+
}
53+
54+
/**
55+
* LIMIT with explicit OFFSET clause.
56+
* Example: limit(10, offset(5))
57+
* @param limit The limit value (maximum number of rows to return).
58+
* @param offset The offset_t instance representing the offset.
59+
* @return limit_t instance representing LIMIT and OFFSET clause.
60+
*/
61+
template<class T, class O>
62+
internal::limit_t<T, true, false, O> limit(T limit, internal::offset_t<O> offset) {
63+
return {std::move(limit), {std::move(offset.offset)}};
64+
}
65+
}

dev/ast/offset.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#pragma once
2+
3+
#include "../functional/cxx_type_traits_polyfill.h"
4+
5+
namespace sqlite_orm {
6+
7+
namespace internal {
8+
/**
9+
* Stores OFFSET only info
10+
*/
11+
template<class T>
12+
struct offset_t {
13+
T offset;
14+
};
15+
16+
template<class T>
17+
using is_offset = polyfill::is_specialization_of<T, offset_t>;
18+
}
19+
20+
/**
21+
* OFFSET clause.
22+
* Example: offset(5)
23+
* @param offset The offset value (number of rows to skip).
24+
* @return offset_t instance representing OFFSET clause.
25+
*/
26+
template<class T>
27+
internal::offset_t<T> offset(T offset) {
28+
return {std::move(offset)};
29+
}
30+
}

dev/ast_iterator.h

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "ast/set.h"
2727
#include "ast/match.h"
2828
#include "ast/cast.h"
29+
#include "ast/limit.h"
2930

3031
namespace sqlite_orm {
3132

@@ -610,8 +611,8 @@ namespace sqlite_orm {
610611
using node_type = as_t<T, E>;
611612

612613
template<class L>
613-
SQLITE_ORM_STATIC_CALLOP void operator()(const node_type& a, L& lambda) SQLITE_ORM_OR_CONST_CALLOP {
614-
iterate_ast(a.expression, lambda);
614+
SQLITE_ORM_STATIC_CALLOP void operator()(const node_type& node, L& lambda) SQLITE_ORM_OR_CONST_CALLOP {
615+
iterate_ast(node.expression, lambda);
615616
}
616617
};
617618

@@ -620,8 +621,8 @@ namespace sqlite_orm {
620621
using node_type = limit_t<T, false, OI, void>;
621622

622623
template<class L>
623-
SQLITE_ORM_STATIC_CALLOP void operator()(const node_type& a, L& lambda) SQLITE_ORM_OR_CONST_CALLOP {
624-
iterate_ast(a.lim, lambda);
624+
SQLITE_ORM_STATIC_CALLOP void operator()(const node_type& node, L& lambda) SQLITE_ORM_OR_CONST_CALLOP {
625+
iterate_ast(node.limit, lambda);
625626
}
626627
};
627628

@@ -630,9 +631,9 @@ namespace sqlite_orm {
630631
using node_type = limit_t<T, true, false, O>;
631632

632633
template<class L>
633-
SQLITE_ORM_STATIC_CALLOP void operator()(const node_type& a, L& lambda) SQLITE_ORM_OR_CONST_CALLOP {
634-
iterate_ast(a.lim, lambda);
635-
a.off.apply([&lambda](auto& value) {
634+
SQLITE_ORM_STATIC_CALLOP void operator()(const node_type& node, L& lambda) SQLITE_ORM_OR_CONST_CALLOP {
635+
iterate_ast(node.limit, lambda);
636+
node.offset.apply([&lambda](auto& value) {
636637
iterate_ast(value, lambda);
637638
});
638639
}
@@ -643,11 +644,11 @@ namespace sqlite_orm {
643644
using node_type = limit_t<T, true, true, O>;
644645

645646
template<class L>
646-
SQLITE_ORM_STATIC_CALLOP void operator()(const node_type& a, L& lambda) SQLITE_ORM_OR_CONST_CALLOP {
647-
a.off.apply([&lambda](auto& value) {
647+
SQLITE_ORM_STATIC_CALLOP void operator()(const node_type& node, L& lambda) SQLITE_ORM_OR_CONST_CALLOP {
648+
node.offset.apply([&lambda](auto& value) {
648649
iterate_ast(value, lambda);
649650
});
650-
iterate_ast(a.lim, lambda);
651+
iterate_ast(node.limit, lambda);
651652
}
652653
};
653654

dev/conditions.h

Lines changed: 0 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -31,44 +31,6 @@ namespace sqlite_orm {
3131

3232
namespace internal {
3333

34-
struct limit_string {
35-
operator std::string() const {
36-
return "LIMIT";
37-
}
38-
};
39-
40-
/**
41-
* Stores LIMIT/OFFSET info
42-
*/
43-
template<class T, bool has_offset, bool offset_is_implicit, class O>
44-
struct limit_t : limit_string {
45-
T lim;
46-
optional_container<O> off;
47-
48-
limit_t() = default;
49-
50-
limit_t(decltype(lim) lim_) : lim(std::move(lim_)) {}
51-
52-
limit_t(decltype(lim) lim_, decltype(off) off_) : lim(std::move(lim_)), off(std::move(off_)) {}
53-
};
54-
55-
template<class T>
56-
struct is_limit : std::false_type {};
57-
58-
template<class T, bool has_offset, bool offset_is_implicit, class O>
59-
struct is_limit<limit_t<T, has_offset, offset_is_implicit, O>> : std::true_type {};
60-
61-
/**
62-
* Stores OFFSET only info
63-
*/
64-
template<class T>
65-
struct offset_t {
66-
T off;
67-
};
68-
69-
template<class T>
70-
using is_offset = polyfill::is_specialization_of<T, offset_t>;
71-
7234
/**
7335
* Collated something
7436
*/
@@ -1003,26 +965,6 @@ SQLITE_ORM_EXPORT namespace sqlite_orm {
1003965
}
1004966
#endif
1005967

1006-
template<class T>
1007-
internal::offset_t<T> offset(T off) {
1008-
return {std::move(off)};
1009-
}
1010-
1011-
template<class T>
1012-
internal::limit_t<T, false, false, void> limit(T lim) {
1013-
return {std::move(lim)};
1014-
}
1015-
1016-
template<class T, class O, internal::satisfies_not<internal::is_offset, T> = true>
1017-
internal::limit_t<T, true, true, O> limit(O off, T lim) {
1018-
return {std::move(lim), {std::move(off)}};
1019-
}
1020-
1021-
template<class T, class O>
1022-
internal::limit_t<T, true, false, O> limit(T lim, internal::offset_t<O> offt) {
1023-
return {std::move(lim), {std::move(offt.off)}};
1024-
}
1025-
1026968
template<class L, class R>
1027969
constexpr auto and_(L l, R r) {
1028970
using namespace ::sqlite_orm::internal;

dev/node_tuple.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "ast/group_by.h"
2626
#include "ast/match.h"
2727
#include "ast/cast.h"
28+
#include "ast/limit.h"
2829

2930
namespace sqlite_orm {
3031
namespace internal {

dev/select_constraints.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "optional_container.h"
2020
#include "ast/where.h"
2121
#include "ast/group_by.h"
22+
#include "ast/limit.h"
2223
#include "core_functions.h"
2324
#include "alias_traits.h"
2425
#include "cte_moniker.h"

dev/statement_serializer.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "ast/match.h"
3030
#include "ast/rank.h"
3131
#include "ast/special_keywords.h"
32+
#include "ast/limit.h"
3233
#include "core_functions.h"
3334
#include "constraints.h"
3435
#include "conditions.h"
@@ -2355,27 +2356,27 @@ namespace sqlite_orm {
23552356
using statement_type = limit_t<T, HO, OI, O>;
23562357

23572358
template<class Ctx>
2358-
SQLITE_ORM_STATIC_CALLOP std::string operator()(const statement_type& limt,
2359+
SQLITE_ORM_STATIC_CALLOP std::string operator()(const statement_type& statement,
23592360
const Ctx& context) SQLITE_ORM_OR_CONST_CALLOP {
23602361
auto newContext = context;
23612362
newContext.skip_table_name = false;
23622363
std::stringstream ss;
2363-
ss << static_cast<std::string>(limt) << " ";
2364+
ss << "LIMIT ";
23642365
if constexpr (HO) {
23652366
if constexpr (OI) {
2366-
limt.off.apply([&newContext, &ss](auto& value) {
2367+
statement.offset.apply([&newContext, &ss](auto& value) {
23672368
ss << serialize(value, newContext);
23682369
});
23692370
ss << ", ";
2370-
ss << serialize(limt.lim, newContext);
2371+
ss << serialize(statement.limit, newContext);
23712372
} else {
2372-
ss << serialize(limt.lim, newContext) << " OFFSET ";
2373-
limt.off.apply([&newContext, &ss](auto& value) {
2373+
ss << serialize(statement.limit, newContext) << " OFFSET ";
2374+
statement.offset.apply([&newContext, &ss](auto& value) {
23742375
ss << serialize(value, newContext);
23752376
});
23762377
}
23772378
} else {
2378-
ss << serialize(limt.lim, newContext);
2379+
ss << serialize(statement.limit, newContext);
23792380
}
23802381
return ss.str();
23812382
}

0 commit comments

Comments
 (0)