Added limit

This commit is contained in:
Dr. Patrick Urbanke
2025-05-01 07:27:40 +02:00
parent f3d687e1bc
commit ebc80d616d
13 changed files with 213 additions and 37 deletions
+2
View File
@@ -11,6 +11,8 @@
#include "sqlgen/Result.hpp"
#include "sqlgen/Varchar.hpp"
#include "sqlgen/col.hpp"
#include "sqlgen/limit.hpp"
#include "sqlgen/order_by.hpp"
#include "sqlgen/read.hpp"
#include "sqlgen/write.hpp"
+1 -3
View File
@@ -1,9 +1,7 @@
#ifndef SQLGEN_DYNAMIC_LIMIT_HPP_
#define SQLGEN_DYNAMIC_LIMIT_HPP_
#include <vector>
#include "Column.hpp"
#include <cstddef>
namespace sqlgen::dynamic {
+29
View File
@@ -0,0 +1,29 @@
#ifndef SQLGEN_LIMIT_HPP_
#define SQLGEN_LIMIT_HPP_
#include <type_traits>
#include "Result.hpp"
#include "read.hpp"
#include "transpilation/Limit.hpp"
#include "transpilation/value_t.hpp"
namespace sqlgen {
using Limit = transpilation::Limit;
template <class ContainerType, class OrderByType, class LimitType>
auto operator|(const Read<ContainerType, OrderByType, LimitType>& _r,
const Limit& _limit) {
static_assert(std::is_same_v<LimitType, Nothing>,
"You cannot call limit twice (but you can order by more "
"than one column).");
return Read<ContainerType, OrderByType, Limit>{.order_by_ = _r.order_by_,
.limit_ = _limit};
}
inline auto limit(const size_t _val) { return Limit{_val}; };
} // namespace sqlgen
#endif
+36
View File
@@ -0,0 +1,36 @@
#ifndef SQLGEN_ORDER_BY_HPP_
#define SQLGEN_ORDER_BY_HPP_
#include <type_traits>
#include "Result.hpp"
#include "read.hpp"
#include "transpilation/order_by_t.hpp"
#include "transpilation/value_t.hpp"
namespace sqlgen {
template <class... ColTypes>
struct OrderBy {};
template <class ContainerType, class OrderByType, class... ColTypes>
auto operator|(const Read<ContainerType, OrderByType>&,
const OrderBy<ColTypes...>&) {
static_assert(std::is_same_v<OrderByType, Nothing>,
"You cannot call order_by twice (but you can order by more "
"than one column).");
static_assert(sizeof...(ColTypes) != 0,
"You must assign at least one column to order by.");
return Read<ContainerType,
transpilation::order_by_t<transpilation::value_t<ContainerType>,
std::remove_cvref_t<ColTypes>...>>{};
}
template <class... ColTypes>
auto order_by(const ColTypes&...) {
return OrderBy<ColTypes...>{};
};
} // namespace sqlgen
#endif
+19 -26
View File
@@ -8,16 +8,18 @@
#include "Ref.hpp"
#include "Result.hpp"
#include "internal/is_range.hpp"
#include "transpilation/OrderBy.hpp"
#include "transpilation/to_select_from.hpp"
#include "transpilation/value_t.hpp"
namespace sqlgen {
template <class ContainerType, class OrderByType>
Result<ContainerType> read_impl(const Ref<Connection>& _conn) {
template <class ContainerType, class OrderByType, class LimitType>
Result<ContainerType> read_impl(const Ref<Connection>& _conn,
const LimitType& _limit) {
using ValueType = transpilation::value_t<ContainerType>;
if constexpr (internal::is_range_v<ContainerType>) {
using ValueType = typename ContainerType::value_type::value_type;
const auto query = transpilation::to_select_from<ValueType, OrderByType>();
const auto query =
transpilation::to_select_from<ValueType, OrderByType>(_limit);
return _conn->read(query).transform(
[](auto&& _it) { return ContainerType(_it); });
@@ -34,42 +36,33 @@ Result<ContainerType> read_impl(const Ref<Connection>& _conn) {
return container;
};
using ValueType = typename ContainerType::value_type;
return read_impl<Range<ValueType>, OrderByType>(_conn).and_then(
to_container);
return read_impl<Range<ValueType>, OrderByType>(_conn, _limit)
.and_then(to_container);
}
}
template <class ContainerType, class OrderByType>
Result<ContainerType> read_impl(const Result<Ref<Connection>>& _res) {
return _res.and_then([](const auto& _conn) {
return read_impl<ContainerType, OrderByType>(_conn);
template <class ContainerType, class OrderByType, class LimitType>
Result<ContainerType> read_impl(const Result<Ref<Connection>>& _res,
const LimitType& _limit) {
return _res.and_then([&](const auto& _conn) {
return read_impl<ContainerType, OrderByType>(_conn, _limit);
});
}
template <class ContainerType, class OrderByType = Nothing>
template <class ContainerType, class OrderByType = Nothing,
class LimitType = Nothing>
struct Read {
Result<ContainerType> operator()(const auto& _conn) const noexcept {
try {
return read_impl<ContainerType, OrderByType>(_conn);
return read_impl<ContainerType, OrderByType>(_conn, limit_);
} catch (std::exception& e) {
return error(e.what());
}
}
template <class... ColTypes>
auto order_by(const ColTypes&...) const noexcept {
static_assert(std::is_same_v<OrderByType, Nothing>,
"order_by is already assigned.");
static_assert(sizeof...(ColTypes) != 0,
"You must assign at least one column to order by.");
return Read<
ContainerType,
transpilation::order_by_t<typename ContainerType::value_type, // TODO
std::remove_cvref_t<ColTypes>...>>{};
}
OrderByType order_by_;
LimitType limit_;
};
template <class ContainerType>
+12
View File
@@ -0,0 +1,12 @@
#ifndef SQLGEN_TRANSPILATION_LIMIT_HPP_
#define SQLGEN_TRANSPILATION_LIMIT_HPP_
#include "../dynamic/Limit.hpp"
namespace sqlgen::transpilation {
using Limit = dynamic::Limit;
} // namespace sqlgen::transpilation
#endif
@@ -1,5 +1,5 @@
#ifndef SQLGEN_TRANSPILATION_ORDERBY_HPP_
#define SQLGEN_TRANSPILATION_ORDERBY_HPP_
#ifndef SQLGEN_TRANSPILATION_ORDERBYT_HPP_
#define SQLGEN_TRANSPILATION_ORDERBYT_HPP_
#include <rfl.hpp>
#include <type_traits>
+30
View File
@@ -0,0 +1,30 @@
#ifndef SQLGEN_TRANSPILATION_TO_LIMIT_HPP_
#define SQLGEN_TRANSPILATION_TO_LIMIT_HPP_
#include <rfl.hpp>
#include <type_traits>
#include <vector>
#include "../Result.hpp"
#include "../dynamic/Limit.hpp"
#include "Limit.hpp"
#include "order_by_t.hpp"
namespace sqlgen::transpilation {
template <class LimitType>
std::optional<dynamic::Limit> to_limit(const LimitType& _limit) {
if constexpr (std::is_same_v<std::remove_cvref_t<LimitType>, Nothing>) {
return std::nullopt;
} else if constexpr (std::is_same_v<std::remove_cvref_t<LimitType>, Limit>) {
return _limit;
} else {
static_assert(rfl::always_false_v<LimitType>, "Unsupported type");
}
}
} // namespace sqlgen::transpilation
#endif
+1 -1
View File
@@ -5,7 +5,7 @@
#include "../Result.hpp"
#include "../dynamic/OrderBy.hpp"
#include "OrderBy.hpp"
#include "order_by_t.hpp"
namespace sqlgen::transpilation {
@@ -14,14 +14,15 @@
#include "get_schema.hpp"
#include "get_tablename.hpp"
#include "make_columns.hpp"
#include "to_limit.hpp"
#include "to_order_by.hpp"
namespace sqlgen::transpilation {
template <class T, class OrderByType = Nothing>
template <class T, class OrderByType = Nothing, class LimitType = Nothing>
requires std::is_class_v<std::remove_cvref_t<T>> &&
std::is_aggregate_v<std::remove_cvref_t<T>>
dynamic::SelectFrom to_select_from() {
dynamic::SelectFrom to_select_from(const LimitType& _limit = LimitType{}) {
using NamedTupleType = rfl::named_tuple_t<std::remove_cvref_t<T>>;
using Fields = typename NamedTupleType::Fields;
@@ -31,7 +32,8 @@ dynamic::SelectFrom to_select_from() {
return dynamic::SelectFrom{.table = dynamic::Table{.name = get_tablename<T>(),
.schema = get_schema<T>()},
.columns = columns,
.order_by = to_order_by<OrderByType>()};
.order_by = to_order_by<OrderByType>(),
.limit = to_limit(_limit)};
}
} // namespace sqlgen::transpilation
+26
View File
@@ -0,0 +1,26 @@
#ifndef SQLGEN_TRANSPILATION_VALUET_HPP_
#define SQLGEN_TRANSPILATION_VALUET_HPP_
#include "../Range.hpp"
namespace sqlgen::transpilation {
template <class ContainerType>
struct ValueType;
template <class ContainerType>
struct ValueType {
using Type = typename ContainerType::value_type;
};
template <class T>
struct ValueType<Range<T>> {
using Type = typename Range<T>::value_type::value_type;
};
template <class T>
using value_t = typename ValueType<T>::Type;
} // namespace sqlgen::transpilation
#endif