Skip to content

Commit 144aa50

Browse files
committed
Replaced enum sort_type in sort_order_expression
with a new struct containing two optionals: + std::optional<sort_type> _l; + std::optional<nulls_pos> _r;
1 parent 5c4d59d commit 144aa50

5 files changed

Lines changed: 183 additions & 7 deletions

File tree

include/sqlpp23/core/clause/union_order_by.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ struct simple_sort_order_expression {
6767
private:
6868
friend reader_t;
6969
simple_column_t<L> _lhs;
70-
sort_type _rhs;
70+
sort_order _rhs;
7171
};
7272

7373
template <typename Context, typename L>

include/sqlpp23/core/operator/comparison_functions.h

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,19 +169,42 @@ enum class sort_type {
169169
template <typename L>
170170
requires(values_are_comparable<L, L>::value)
171171
constexpr auto asc(L l) -> sort_order_expression<L> {
172-
return {l, sort_type::asc};
172+
return {std::move(l), {sort_type::asc, std::nullopt}};
173173
}
174174

175175
template <typename L>
176176
requires(values_are_comparable<L, L>::value)
177177
constexpr auto desc(L l) -> sort_order_expression<L> {
178-
return {l, sort_type::desc};
178+
return {std::move(l), {sort_type::desc, std::nullopt}};
179179
}
180180

181181
template <typename L>
182182
requires(values_are_comparable<L, L>::value)
183183
constexpr auto order(L l, sort_type order) -> sort_order_expression<L> {
184-
return {l, order};
184+
return {std::move(l), {std::move(order), std::nullopt}};
185+
}
186+
187+
enum class nulls_pos {
188+
first,
189+
last,
190+
};
191+
192+
template <typename L>
193+
requires(values_are_comparable<L, L>::value)
194+
constexpr auto nulls_first(L l) -> sort_order_expression<L> {
195+
return {std::move(l), {std::nullopt , nulls_pos::first}};
196+
}
197+
198+
template <typename L>
199+
requires(values_are_comparable<L, L>::value)
200+
constexpr auto nulls_last(L l) -> sort_order_expression<L> {
201+
return {std::move(l), {std::nullopt , nulls_pos::last}};
202+
}
203+
204+
template <typename L>
205+
requires(values_are_comparable<L, L>::value)
206+
constexpr auto nulls_order(L l, nulls_pos pos) -> sort_order_expression<L> {
207+
return {std::move(l), {std::nullopt , std::move(pos)}};
185208
}
186209

187210
} // namespace sqlpp

include/sqlpp23/core/operator/enable_comparison.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,24 @@ class enable_comparison {
125125
return ::sqlpp::order(std::forward<Expr>(self), t);
126126
}
127127

128+
template <typename Expr>
129+
constexpr auto nulls_first(this Expr&& self)
130+
-> decltype(::sqlpp::nulls_first(std::forward<Expr>(self))) {
131+
return ::sqlpp::nulls_first(std::forward<Expr>(self));
132+
}
133+
134+
template <typename Expr>
135+
constexpr auto nulls_last(this Expr&& self)
136+
-> decltype(::sqlpp::nulls_last(std::forward<Expr>(self))) {
137+
return ::sqlpp::nulls_last(std::forward<Expr>(self));
138+
}
139+
140+
template <typename Expr>
141+
constexpr auto nulls_order(this Expr&& self, ::sqlpp::nulls_pos t)
142+
-> decltype(::sqlpp::nulls_order(std::forward<Expr>(self), t)) {
143+
return ::sqlpp::nulls_order(std::forward<Expr>(self), t);
144+
}
145+
128146
template <typename Expr, typename R>
129147
constexpr auto like(this Expr&& self, R r)
130148
-> decltype(::sqlpp::like(std::forward<Expr>(self), std::move(r))) {

include/sqlpp23/core/operator/sort_order_expression.h

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,22 +32,58 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3232
#include <sqlpp23/core/reader.h>
3333

3434
namespace sqlpp {
35+
36+
struct sort_order {
37+
constexpr sort_order(std::optional<sort_type> l = std::nullopt, std::optional<nulls_pos> r = std::nullopt)
38+
: _lhs(std::move(l)), _rhs(std::move(r)) {}
39+
sort_order(const sort_order&) = default;
40+
sort_order(sort_order&&) = default;
41+
sort_order& operator=(const sort_order&) = default;
42+
sort_order& operator=(sort_order&&) = default;
43+
~sort_order() = default;
44+
45+
std::optional<sort_type> _lhs;
46+
std::optional<nulls_pos> _rhs;
47+
};
48+
3549
template <typename L>
3650
struct sort_order_expression {
37-
constexpr sort_order_expression(L l, sort_type r)
51+
constexpr sort_order_expression(L l, sort_order r)
3852
: _lhs(std::move(l)), _rhs(std::move(r)) {}
3953
sort_order_expression(const sort_order_expression&) = default;
4054
sort_order_expression(sort_order_expression&&) = default;
4155
sort_order_expression& operator=(const sort_order_expression&) = default;
4256
sort_order_expression& operator=(sort_order_expression&&) = default;
4357
~sort_order_expression() = default;
4458

59+
constexpr auto nulls_first() -> sort_order_expression<L>;
60+
constexpr auto nulls_last() -> sort_order_expression<L>;
61+
constexpr auto nulls_order(::sqlpp::nulls_pos t) -> sort_order_expression<L>;
62+
4563
private:
4664
friend reader_t;
47-
L _lhs;
48-
sort_type _rhs;
65+
const L _lhs;
66+
const sort_order _rhs;
67+
};
68+
69+
template <typename L>
70+
constexpr auto sort_order_expression<L>::nulls_first() -> sort_order_expression<L> {
71+
static_assert(_rhs._rhs.has_value(), "nulls_first() can only be called when nulls_pos is not already set.");
72+
return {std::move(_lhs), {std::move(_rhs._lhs), ::sqlpp::nulls_pos::first}};
73+
}
74+
75+
template <typename L>
76+
constexpr auto sort_order_expression<L>::nulls_last() -> sort_order_expression<L> {
77+
static_assert(_rhs._rhs.has_value(), "nulls_last() can only be called when nulls_pos is not already set.");
78+
return {std::move(_lhs), {std::move(_rhs._lhs), ::sqlpp::nulls_pos::last}};
4979
};
5080

81+
template <typename L>
82+
constexpr auto sort_order_expression<L>::nulls_order(::sqlpp::nulls_pos t) -> sort_order_expression<L> {
83+
static_assert(_rhs._rhs.has_value(), "nulls_order(::sqlpp::nulls_pos t) can only be called when nulls_pos is not already set.");
84+
return {std::move(_lhs), {std::move(_rhs._lhs), std::move(t)}};
85+
}
86+
5187
template <typename L>
5288
struct nodes_of<sort_order_expression<L>> {
5389
using type = detail::type_vector<L>;
@@ -64,6 +100,20 @@ auto to_sql_string(Context&, const sort_type& t) -> std::string {
64100
return " DESC";
65101
}
66102

103+
template <typename Context>
104+
auto to_sql_string(Context&, const nulls_pos& t) -> std::string {
105+
if (t == nulls_pos::first) {
106+
return " NULLS FIRST";
107+
}
108+
return " NULLS LAST";
109+
}
110+
111+
template <typename Context>
112+
auto to_sql_string(Context& context, const sort_order& t)
113+
-> std::string {
114+
return to_sql_string(context, read.lhs(t)) + to_sql_string(context, read.rhs(t));
115+
}
116+
67117
template <typename Context, typename L>
68118
auto to_sql_string(Context& context, const sort_order_expression<L>& t)
69119
-> std::string {
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright (c) 2024, Roland Bock
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
*
8+
* * Redistributions of source code must retain the above copyright notice,
9+
* this list of conditions and the following disclaimer.
10+
* * Redistributions in binary form must reproduce the above copyright notice,
11+
* this list of conditions and the following disclaimer in the documentation
12+
* and/or other materials provided with the distribution.
13+
*
14+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24+
* POSSIBILITY OF SUCH DAMAGE.
25+
*/
26+
27+
#include <sqlpp23/tests/core/all.h>
28+
29+
int main(int, char*[]) {
30+
const auto val = sqlpp::value(1);
31+
const auto expr = sqlpp::value(17) + 4;
32+
33+
// Operands are enclosed in parentheses where required.
34+
SQLPP_COMPARE(val.nulls_last(), "1 NULLS LAST");
35+
SQLPP_COMPARE(val.nulls_order(sqlpp::nulls_pos::first), "1 NULLS FIRST");
36+
SQLPP_COMPARE(val.nulls_order(sqlpp::nulls_pos::last), "1 NULLS LAST");
37+
SQLPP_COMPARE(val.nulls_first(), "1 NULLS FIRST");
38+
SQLPP_COMPARE(val.asc(), "1 ASC");
39+
SQLPP_COMPARE(val.asc().nulls_first(), "1 ASC NULLS FIRST");
40+
SQLPP_COMPARE(val.asc().nulls_last(), "1 ASC NULLS LAST");
41+
SQLPP_COMPARE(val.asc().nulls_order(sqlpp::nulls_pos::first), "1 ASC NULLS FIRST");
42+
SQLPP_COMPARE(val.asc().nulls_order(sqlpp::nulls_pos::last), "1 ASC NULLS LAST");
43+
SQLPP_COMPARE(val.desc(), "1 DESC");
44+
SQLPP_COMPARE(val.desc().nulls_first(), "1 DESC NULLS FIRST");
45+
SQLPP_COMPARE(val.desc().nulls_last(), "1 DESC NULLS LAST");
46+
SQLPP_COMPARE(val.desc().nulls_order(sqlpp::nulls_pos::first), "1 DESC NULLS FIRST");
47+
SQLPP_COMPARE(val.desc().nulls_order(sqlpp::nulls_pos::last), "1 DESC NULLS LAST");
48+
SQLPP_COMPARE(val.order(sqlpp::sort_type::asc), "1 ASC");
49+
SQLPP_COMPARE(val.order(sqlpp::sort_type::asc).nulls_first().nulls_first(), "1 ASC NULLS FIRST");
50+
SQLPP_COMPARE(val.order(sqlpp::sort_type::asc).nulls_last(), "1 ASC NULLS LAST");
51+
SQLPP_COMPARE(val.order(sqlpp::sort_type::asc).nulls_order(sqlpp::nulls_pos::first), "1 ASC NULLS FIRST");
52+
SQLPP_COMPARE(val.order(sqlpp::sort_type::asc).nulls_order(sqlpp::nulls_pos::last), "1 ASC NULLS LAST");
53+
SQLPP_COMPARE(val.order(sqlpp::sort_type::desc), "1 DESC");
54+
SQLPP_COMPARE(val.order(sqlpp::sort_type::desc).nulls_first(), "1 DESC NULLS FIRST");
55+
SQLPP_COMPARE(val.order(sqlpp::sort_type::desc).nulls_last(), "1 DESC NULLS LAST");
56+
SQLPP_COMPARE(val.order(sqlpp::sort_type::desc).nulls_order(sqlpp::nulls_pos::first), "1 DESC NULLS FIRST");
57+
SQLPP_COMPARE(val.order(sqlpp::sort_type::desc).nulls_order(sqlpp::nulls_pos::last), "1 DESC NULLS LAST");
58+
59+
SQLPP_COMPARE(expr.nulls_first(), "(17 + 4) NULLS FIRST");
60+
SQLPP_COMPARE(expr.nulls_last(), "(17 + 4) NULLS LAST");
61+
SQLPP_COMPARE(expr.nulls_order(sqlpp::nulls_pos::first), "(17 + 4) NULLS FIRST");
62+
SQLPP_COMPARE(expr.nulls_order(sqlpp::nulls_pos::last), "(17 + 4) NULLS LAST");
63+
SQLPP_COMPARE(expr.asc(), "(17 + 4) ASC");
64+
SQLPP_COMPARE(expr.asc().nulls_first(), "(17 + 4) ASC NULLS FIRST");
65+
SQLPP_COMPARE(expr.asc().nulls_last(), "(17 + 4) ASC NULLS LAST");
66+
SQLPP_COMPARE(expr.asc().nulls_order(sqlpp::nulls_pos::first), "(17 + 4) ASC NULLS FIRST");
67+
SQLPP_COMPARE(expr.asc().nulls_order(sqlpp::nulls_pos::last), "(17 + 4) ASC NULLS LAST");
68+
SQLPP_COMPARE(expr.desc(), "(17 + 4) DESC");
69+
SQLPP_COMPARE(expr.desc().nulls_first(), "(17 + 4) DESC NULLS FIRST");
70+
SQLPP_COMPARE(expr.desc().nulls_last(), "(17 + 4) DESC NULLS LAST");
71+
SQLPP_COMPARE(expr.desc().nulls_order(sqlpp::nulls_pos::first), "(17 + 4) DESC NULLS FIRST");
72+
SQLPP_COMPARE(expr.desc().nulls_order(sqlpp::nulls_pos::last), "(17 + 4) DESC NULLS LAST");
73+
SQLPP_COMPARE(expr.order(sqlpp::sort_type::asc), "(17 + 4) ASC");
74+
SQLPP_COMPARE(expr.order(sqlpp::sort_type::asc).nulls_first(), "(17 + 4) ASC NULLS FIRST");
75+
SQLPP_COMPARE(expr.order(sqlpp::sort_type::asc).nulls_last(), "(17 + 4) ASC NULLS LAST");
76+
SQLPP_COMPARE(expr.order(sqlpp::sort_type::asc).nulls_order(sqlpp::nulls_pos::first), "(17 + 4) ASC NULLS FIRST");
77+
SQLPP_COMPARE(expr.order(sqlpp::sort_type::asc).nulls_order(sqlpp::nulls_pos::last), "(17 + 4) ASC NULLS LAST");
78+
SQLPP_COMPARE(expr.order(sqlpp::sort_type::desc), "(17 + 4) DESC");
79+
SQLPP_COMPARE(expr.order(sqlpp::sort_type::desc).nulls_first(), "(17 + 4) DESC NULLS FIRST");
80+
SQLPP_COMPARE(expr.order(sqlpp::sort_type::desc).nulls_last(), "(17 + 4) DESC NULLS LAST");
81+
SQLPP_COMPARE(expr.order(sqlpp::sort_type::desc).nulls_order(sqlpp::nulls_pos::first), "(17 + 4) DESC NULLS FIRST");
82+
SQLPP_COMPARE(expr.order(sqlpp::sort_type::desc).nulls_order(sqlpp::nulls_pos::last), "(17 + 4) DESC NULLS LAST");
83+
84+
return 0;
85+
}

0 commit comments

Comments
 (0)