Skip to content

Commit d2fd28b

Browse files
authored
Merge pull request #236 from qicosmos/limit_offset_token
2 parents a5b15ee + 8a7b7df commit d2fd28b

2 files changed

Lines changed: 59 additions & 13 deletions

File tree

ormpp/query.hpp

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,9 @@ auto operator<=(aggregate_field<M> field, auto val) {
233233
return build_where(field, val, "<=");
234234
}
235235

236+
struct token_t {};
237+
inline constexpr auto token = token_t{};
238+
236239
inline auto count() { return aggregate_field<uint64_t>{"COUNT(*)"}; }
237240

238241
template <typename T>
@@ -357,19 +360,6 @@ class query_builder {
357360
where_clause_.insert(0, " where ");
358361
}
359362
}
360-
#ifdef ORMPP_ENABLE_PG
361-
if (!where_clause_.empty()) {
362-
int index = 1;
363-
for (size_t i = 0; i < where_clause_.size(); i++) {
364-
if (where_clause_[i] == '?') {
365-
where_clause_[i] = '$';
366-
std::string index_str = std::to_string(index++);
367-
std::memcpy(&where_clause_[i + 1], index_str.data(),
368-
(std::min)(index_str.size(), size_t(2)));
369-
}
370-
}
371-
}
372-
#endif
373363

374364
sql_.append(join_clause_)
375365
.append(where_clause_)
@@ -380,6 +370,20 @@ class query_builder {
380370
.append(limit_clause_)
381371
.append(offset_clause_);
382372

373+
#ifdef ORMPP_ENABLE_PG
374+
if (sql_.find('?') != std::string::npos) {
375+
int index = 1;
376+
for (size_t i = 0; i < sql_.size(); i++) {
377+
if (sql_[i] == '?') {
378+
sql_[i] = '$';
379+
std::string index_str = std::to_string(index++);
380+
std::memcpy(&sql_[i + 1], index_str.data(),
381+
(std::min)(index_str.size(), size_t(2)));
382+
}
383+
}
384+
}
385+
#endif
386+
383387
if constexpr (!ylt::reflection::is_ylt_refl_v<R> && !std::is_void_v<R> &&
384388
!iguana::tuple_v<R>) {
385389
auto t = db_->template query_s<std::tuple<R>>(sql_, args...);
@@ -448,6 +452,11 @@ class query_builder {
448452
return stage_offset{ctx};
449453
}
450454

455+
stage_offset offset(token_t) {
456+
ctx->offset_clause_.append(" offset ? ");
457+
return stage_offset{ctx};
458+
}
459+
451460
template <typename To, typename... Args>
452461
auto collect(Args... args) {
453462
return ctx->template collect<To>(args...);
@@ -467,6 +476,11 @@ class query_builder {
467476
return stage_limit{ctx};
468477
}
469478

479+
stage_limit limit(token_t) {
480+
ctx->limit_clause_ = " LIMIT ? ";
481+
return stage_limit{ctx};
482+
}
483+
470484
template <typename To, typename... Args>
471485
auto collect(Args... args) {
472486
return ctx->template collect<To>(args...);
@@ -550,6 +564,11 @@ class query_builder {
550564
return stage_limit{ctx};
551565
}
552566

567+
stage_limit limit(token_t) {
568+
ctx->limit_c = " LIMIT ? ";
569+
return stage_limit{ctx};
570+
}
571+
553572
template <typename... Args>
554573
stage_group_by group_by(Args... fields) {
555574
ctx->group_by_clause_ = " GROUP BY ";

tests/test_ormpp.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,14 @@ TEST_CASE("optional") {
289289
CHECK(l3.size() == 2);
290290
CHECK(l4.size() == 2);
291291
}
292+
auto l0 = mysql.select(all)
293+
.from<test_optional>()
294+
.where(col(&test_optional::id).in(1, 2))
295+
.order_by(col(&test_optional::id).desc(),
296+
col(&test_optional::name).desc())
297+
.limit(token)
298+
.offset(token)
299+
.collect(5, 0);
292300
auto l1 = mysql.select(all)
293301
.from<test_optional>()
294302
.where(col(&test_optional::id).in(1, 2))
@@ -316,6 +324,7 @@ TEST_CASE("optional") {
316324
.from<test_optional>()
317325
.where(col(&test_optional::name).in("test", "purecpp"))
318326
.collect();
327+
CHECK(l0.size() == 2);
319328
CHECK(l1.size() == 2);
320329
CHECK(l2.size() == 2);
321330

@@ -501,6 +510,14 @@ TEST_CASE("optional") {
501510
CHECK(l3.size() == 2);
502511
CHECK(l4.size() == 2);
503512
}
513+
auto l0 = postgres.select(all)
514+
.from<test_optional>()
515+
.where(col(&test_optional::id).in(1, 2))
516+
.order_by(col(&test_optional::id).desc(),
517+
col(&test_optional::name).desc())
518+
.limit(token)
519+
.offset(token)
520+
.collect(5, 0);
504521
auto l1 = postgres.select(all)
505522
.from<test_optional>()
506523
.where(col(&test_optional::id).in(1, 2))
@@ -528,6 +545,7 @@ TEST_CASE("optional") {
528545
.from<test_optional>()
529546
.where(col(&test_optional::name).in("test", "purecpp"))
530547
.collect();
548+
CHECK(l0.size() == 2);
531549
CHECK(l1.size() == 2);
532550
CHECK(l2.size() == 2);
533551

@@ -725,6 +743,14 @@ TEST_CASE("optional") {
725743
CHECK(l2.size() == 1);
726744
sqlite.execute("DROP TABLE IF EXISTS person");
727745
}
746+
auto l0 = sqlite.select(all)
747+
.from<test_optional>()
748+
.where(col(&test_optional::id).in(1, 2))
749+
.order_by(col(&test_optional::id).desc(),
750+
col(&test_optional::name).desc())
751+
.limit(token)
752+
.offset(token)
753+
.collect(5, 0);
728754
auto l1 = sqlite.select(all)
729755
.from<test_optional>()
730756
.where(col(&test_optional::id).in(1, 2))
@@ -753,6 +779,7 @@ TEST_CASE("optional") {
753779
.from<test_optional>()
754780
.where(col(&test_optional::name).in("test", "purecpp"))
755781
.collect();
782+
CHECK(l0.size() == 2);
756783
CHECK(l1.size() == 2);
757784
CHECK(l2.size() == 2);
758785

0 commit comments

Comments
 (0)