mirror of
https://github.com/getml/sqlgen.git
synced 2026-05-20 15:40:32 -05:00
Added limit
This commit is contained in:
@@ -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,9 +1,7 @@
|
||||
#ifndef SQLGEN_DYNAMIC_LIMIT_HPP_
|
||||
#define SQLGEN_DYNAMIC_LIMIT_HPP_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "Column.hpp"
|
||||
#include <cstddef>
|
||||
|
||||
namespace sqlgen::dynamic {
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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>
|
||||
|
||||
@@ -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
|
||||
+2
-2
@@ -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>
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user