mirror of
https://github.com/getml/sqlgen.git
synced 2026-01-05 00:49:58 -06:00
Added the ability to add subqueries in select_from (#39)
This commit is contained in:
committed by
GitHub
parent
ad1cae049b
commit
f536efbde9
@@ -18,6 +18,8 @@
|
||||
namespace sqlgen::dynamic {
|
||||
|
||||
struct SelectFrom {
|
||||
using TableOrQueryType = rfl::Variant<Table, Ref<SelectFrom>>;
|
||||
|
||||
struct Field {
|
||||
Operation val;
|
||||
std::optional<std::string> as;
|
||||
@@ -25,12 +27,12 @@ struct SelectFrom {
|
||||
|
||||
struct Join {
|
||||
JoinType how;
|
||||
rfl::Variant<Table, Ref<SelectFrom>> table_or_query;
|
||||
TableOrQueryType table_or_query;
|
||||
std::string alias;
|
||||
std::optional<Condition> on;
|
||||
};
|
||||
|
||||
Table table;
|
||||
TableOrQueryType table_or_query;
|
||||
std::vector<Field> fields;
|
||||
std::optional<std::string> alias = std::nullopt;
|
||||
std::optional<std::vector<Join>> joins = std::nullopt;
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "order_by.hpp"
|
||||
#include "to.hpp"
|
||||
#include "transpilation/Join.hpp"
|
||||
#include "transpilation/TableWrapper.hpp"
|
||||
#include "transpilation/fields_to_named_tuple_t.hpp"
|
||||
#include "transpilation/group_by_t.hpp"
|
||||
#include "transpilation/order_by_t.hpp"
|
||||
@@ -31,19 +32,20 @@
|
||||
namespace sqlgen {
|
||||
|
||||
template <class TableTupleType, class AliasType, class FieldsType,
|
||||
class JoinsType, class WhereType, class GroupByType,
|
||||
class OrderByType, class LimitType, class ContainerType,
|
||||
class Connection>
|
||||
class TableOrQueryType, class JoinsType, class WhereType,
|
||||
class GroupByType, class OrderByType, class LimitType,
|
||||
class ContainerType, class Connection>
|
||||
requires is_connection<Connection>
|
||||
auto select_from_impl(const Ref<Connection>& _conn, const FieldsType& _fields,
|
||||
const TableOrQueryType& _table_or_query,
|
||||
const JoinsType& _joins, const WhereType& _where,
|
||||
const LimitType& _limit) {
|
||||
if constexpr (internal::is_range_v<ContainerType>) {
|
||||
const auto query =
|
||||
transpilation::to_select_from<TableTupleType, AliasType, FieldsType,
|
||||
JoinsType, WhereType, GroupByType,
|
||||
OrderByType, LimitType>(_fields, _joins,
|
||||
_where, _limit);
|
||||
TableOrQueryType, JoinsType, WhereType,
|
||||
GroupByType, OrderByType, LimitType>(
|
||||
_fields, _table_or_query, _joins, _where, _limit);
|
||||
return _conn->read(query).transform(
|
||||
[](auto&& _it) { return ContainerType(_it); });
|
||||
|
||||
@@ -65,36 +67,40 @@ auto select_from_impl(const Ref<Connection>& _conn, const FieldsType& _fields,
|
||||
using RangeType = Range<
|
||||
transpilation::fields_to_named_tuple_t<TableTupleType, FieldsType>>;
|
||||
|
||||
return select_from_impl<TableTupleType, AliasType, FieldsType, JoinsType,
|
||||
WhereType, GroupByType, OrderByType, LimitType,
|
||||
RangeType>(_conn, _fields, _joins, _where, _limit)
|
||||
return select_from_impl<TableTupleType, AliasType, FieldsType,
|
||||
TableOrQueryType, JoinsType, WhereType, GroupByType,
|
||||
OrderByType, LimitType, RangeType>(
|
||||
_conn, _fields, _table_or_query, _joins, _where, _limit)
|
||||
.and_then(to_container);
|
||||
}
|
||||
}
|
||||
|
||||
template <class TableTupleType, class AliasType, class FieldsType,
|
||||
class JoinsType, class WhereType, class GroupByType,
|
||||
class OrderByType, class LimitType, class ContainerType,
|
||||
class Connection>
|
||||
class TableOrQueryType, class JoinsType, class WhereType,
|
||||
class GroupByType, class OrderByType, class LimitType,
|
||||
class ContainerType, class Connection>
|
||||
requires is_connection<Connection>
|
||||
auto select_from_impl(const Result<Ref<Connection>>& _res,
|
||||
const FieldsType& _fields, const JoinsType& _joins,
|
||||
const WhereType& _where, const LimitType& _limit) {
|
||||
const FieldsType& _fields,
|
||||
const TableOrQueryType& _table_or_query,
|
||||
const JoinsType& _joins, const WhereType& _where,
|
||||
const LimitType& _limit) {
|
||||
return _res.and_then([&](const auto& _conn) {
|
||||
return select_from_impl<TableTupleType, AliasType, FieldsType, JoinsType,
|
||||
WhereType, GroupByType, OrderByType, LimitType,
|
||||
ContainerType>(_conn, _joins, _where, _limit);
|
||||
return select_from_impl<TableTupleType, AliasType, FieldsType,
|
||||
TableOrQueryType, JoinsType, WhereType, GroupByType,
|
||||
OrderByType, LimitType, ContainerType>(
|
||||
_conn, _table_or_query, _joins, _where, _limit);
|
||||
});
|
||||
}
|
||||
|
||||
template <class StructType, class AliasType, class FieldsType,
|
||||
template <class TableOrQueryType, class AliasType, class FieldsType,
|
||||
class JoinsType = Nothing, class WhereType = Nothing,
|
||||
class GroupByType = Nothing, class OrderByType = Nothing,
|
||||
class LimitType = Nothing, class ToType = Nothing>
|
||||
struct SelectFrom {
|
||||
auto operator()(const auto& _conn) const {
|
||||
using TableTupleType =
|
||||
transpilation::table_tuple_t<StructType, AliasType, JoinsType>;
|
||||
transpilation::table_tuple_t<TableOrQueryType, AliasType, JoinsType>;
|
||||
|
||||
if constexpr (std::is_same_v<ToType, Nothing> ||
|
||||
std::ranges::input_range<std::remove_cvref_t<ToType>>) {
|
||||
@@ -103,10 +109,10 @@ struct SelectFrom {
|
||||
Range<transpilation::fields_to_named_tuple_t<
|
||||
TableTupleType, FieldsType>>,
|
||||
ToType>;
|
||||
return select_from_impl<TableTupleType, AliasType, FieldsType, JoinsType,
|
||||
WhereType, GroupByType, OrderByType, LimitType,
|
||||
ContainerType>(_conn, fields_, joins_, where_,
|
||||
limit_);
|
||||
return select_from_impl<
|
||||
TableTupleType, AliasType, FieldsType, TableOrQueryType, JoinsType,
|
||||
WhereType, GroupByType, OrderByType, LimitType, ContainerType>(
|
||||
_conn, fields_, from_, joins_, where_, limit_);
|
||||
|
||||
} else {
|
||||
const auto extract_result = [](auto&& _vec) -> Result<ToType> {
|
||||
@@ -119,19 +125,20 @@ struct SelectFrom {
|
||||
return std::move(_vec[0]);
|
||||
};
|
||||
|
||||
return select_from_impl<TableTupleType, AliasType, FieldsType, JoinsType,
|
||||
WhereType, GroupByType, OrderByType, LimitType,
|
||||
return select_from_impl<TableTupleType, AliasType, FieldsType,
|
||||
TableOrQueryType, JoinsType, WhereType,
|
||||
GroupByType, OrderByType, LimitType,
|
||||
std::vector<std::remove_cvref_t<ToType>>>(
|
||||
_conn, fields_, joins_, where_, limit_)
|
||||
_conn, fields_, from_, joins_, where_, limit_)
|
||||
.and_then(extract_result);
|
||||
}
|
||||
}
|
||||
|
||||
template <class TableOrQueryType, class ConditionType,
|
||||
template <class OtherTableOrQueryType, class ConditionType,
|
||||
rfl::internal::StringLiteral _alias>
|
||||
friend auto operator|(
|
||||
const SelectFrom& _s,
|
||||
const transpilation::Join<TableOrQueryType, ConditionType, _alias>&
|
||||
const transpilation::Join<OtherTableOrQueryType, ConditionType, _alias>&
|
||||
_join) {
|
||||
static_assert(std::is_same_v<WhereType, Nothing>,
|
||||
"You cannot call where(...) before a join.");
|
||||
@@ -146,23 +153,25 @@ struct SelectFrom {
|
||||
|
||||
if constexpr (std::is_same_v<JoinsType, Nothing>) {
|
||||
using NewJoinsType = rfl::Tuple<
|
||||
transpilation::Join<TableOrQueryType, ConditionType, _alias>>;
|
||||
transpilation::Join<OtherTableOrQueryType, ConditionType, _alias>>;
|
||||
|
||||
return SelectFrom<StructType, AliasType, FieldsType, NewJoinsType,
|
||||
return SelectFrom<TableOrQueryType, AliasType, FieldsType, NewJoinsType,
|
||||
WhereType, GroupByType, OrderByType, LimitType, ToType>{
|
||||
.fields_ = _s.fields_, .joins_ = NewJoinsType(_join)};
|
||||
.fields_ = _s.fields_,
|
||||
.from_ = _s.from_,
|
||||
.joins_ = NewJoinsType(_join)};
|
||||
|
||||
} else {
|
||||
using TupleType = rfl::Tuple<
|
||||
transpilation::Join<TableOrQueryType, ConditionType, _alias>>;
|
||||
transpilation::Join<OtherTableOrQueryType, ConditionType, _alias>>;
|
||||
|
||||
const auto joins = rfl::tuple_cat(_s.joins_, TupleType(_join));
|
||||
|
||||
using NewJoinsType = std::remove_cvref_t<decltype(joins)>;
|
||||
|
||||
return SelectFrom<StructType, AliasType, FieldsType, NewJoinsType,
|
||||
return SelectFrom<TableOrQueryType, AliasType, FieldsType, NewJoinsType,
|
||||
WhereType, GroupByType, OrderByType, LimitType, ToType>{
|
||||
.fields_ = _s.fields_, .joins_ = joins};
|
||||
.fields_ = _s.fields_, .from_ = _s.from_, .joins_ = joins};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,10 +189,12 @@ struct SelectFrom {
|
||||
"You cannot call limit(...) before where(...).");
|
||||
static_assert(std::is_same_v<ToType, Nothing>,
|
||||
"You cannot call to<...> before where(...).");
|
||||
return SelectFrom<StructType, AliasType, FieldsType, JoinsType,
|
||||
return SelectFrom<TableOrQueryType, AliasType, FieldsType, JoinsType,
|
||||
ConditionType, GroupByType, OrderByType, LimitType,
|
||||
ToType>{
|
||||
.fields_ = _s.fields_, .joins_ = _s.joins_, .where_ = _where.condition};
|
||||
ToType>{.fields_ = _s.fields_,
|
||||
.from_ = _s.from_,
|
||||
.joins_ = _s.joins_,
|
||||
.where_ = _where.condition};
|
||||
}
|
||||
|
||||
template <class... ColTypes>
|
||||
@@ -200,11 +211,14 @@ struct SelectFrom {
|
||||
"You cannot call to<...> before group_by(...).");
|
||||
static_assert(sizeof...(ColTypes) != 0,
|
||||
"You must assign at least one column to group_by.");
|
||||
return SelectFrom<
|
||||
StructType, AliasType, FieldsType, JoinsType, WhereType,
|
||||
transpilation::group_by_t<StructType, typename ColTypes::ColType...>,
|
||||
OrderByType, LimitType, ToType>{
|
||||
.fields_ = _s.fields_, .joins_ = _s.joins_, .where_ = _s.where_};
|
||||
return SelectFrom<TableOrQueryType, AliasType, FieldsType, JoinsType,
|
||||
WhereType,
|
||||
transpilation::group_by_t<TableOrQueryType,
|
||||
typename ColTypes::ColType...>,
|
||||
OrderByType, LimitType, ToType>{.fields_ = _s.fields_,
|
||||
.from_ = _s.from_,
|
||||
.joins_ = _s.joins_,
|
||||
.where_ = _s.where_};
|
||||
}
|
||||
|
||||
template <class... ColTypes>
|
||||
@@ -221,23 +235,27 @@ struct SelectFrom {
|
||||
"You must assign at least one column to order_by.");
|
||||
|
||||
using TableTupleType =
|
||||
transpilation::table_tuple_t<StructType, AliasType, JoinsType>;
|
||||
transpilation::table_tuple_t<TableOrQueryType, AliasType, JoinsType>;
|
||||
|
||||
using NewOrderByType = transpilation::order_by_t<
|
||||
TableTupleType, GroupByType,
|
||||
typename std::remove_cvref_t<ColTypes>::ColType...>;
|
||||
|
||||
return SelectFrom<StructType, AliasType, FieldsType, JoinsType, WhereType,
|
||||
GroupByType, NewOrderByType, LimitType, ToType>{
|
||||
.fields_ = _s.fields_, .joins_ = _s.joins_, .where_ = _s.where_};
|
||||
return SelectFrom<TableOrQueryType, AliasType, FieldsType, JoinsType,
|
||||
WhereType, GroupByType, NewOrderByType, LimitType,
|
||||
ToType>{.fields_ = _s.fields_,
|
||||
.from_ = _s.from_,
|
||||
.joins_ = _s.joins_,
|
||||
.where_ = _s.where_};
|
||||
}
|
||||
|
||||
friend auto operator|(const SelectFrom& _s, const Limit& _limit) {
|
||||
static_assert(std::is_same_v<LimitType, Nothing>,
|
||||
"You cannot call limit twice.");
|
||||
return SelectFrom<StructType, AliasType, FieldsType, JoinsType, WhereType,
|
||||
GroupByType, OrderByType, Limit, ToType>{
|
||||
return SelectFrom<TableOrQueryType, AliasType, FieldsType, JoinsType,
|
||||
WhereType, GroupByType, OrderByType, Limit, ToType>{
|
||||
.fields_ = _s.fields_,
|
||||
.from_ = _s.from_,
|
||||
.joins_ = _s.joins_,
|
||||
.where_ = _s.where_,
|
||||
.limit_ = _limit};
|
||||
@@ -247,16 +265,19 @@ struct SelectFrom {
|
||||
friend auto operator|(const SelectFrom& _s, const To<NewToType>&) {
|
||||
static_assert(std::is_same_v<ToType, Nothing>,
|
||||
"You cannot call to<...> twice.");
|
||||
return SelectFrom<StructType, AliasType, FieldsType, JoinsType, WhereType,
|
||||
GroupByType, OrderByType, LimitType, NewToType>{
|
||||
.fields_ = _s.fields_,
|
||||
.joins_ = _s.joins_,
|
||||
.where_ = _s.where_,
|
||||
.limit_ = _s.limit_};
|
||||
return SelectFrom<TableOrQueryType, AliasType, FieldsType, JoinsType,
|
||||
WhereType, GroupByType, OrderByType, LimitType,
|
||||
NewToType>{.fields_ = _s.fields_,
|
||||
.from_ = _s.from_,
|
||||
.joins_ = _s.joins_,
|
||||
.where_ = _s.where_,
|
||||
.limit_ = _s.limit_};
|
||||
}
|
||||
|
||||
FieldsType fields_;
|
||||
|
||||
TableOrQueryType from_;
|
||||
|
||||
JoinsType joins_;
|
||||
|
||||
WhereType where_;
|
||||
@@ -266,62 +287,66 @@ struct SelectFrom {
|
||||
|
||||
namespace transpilation {
|
||||
|
||||
template <class StructType, class AliasType, class FieldsType, class JoinsType,
|
||||
class... Args>
|
||||
template <class TableOrQueryType, class AliasType, class FieldsType,
|
||||
class JoinsType, class... Args>
|
||||
struct ExtractTable<
|
||||
SelectFrom<StructType, AliasType, FieldsType, JoinsType, Args...>> {
|
||||
using TableTupleType = table_tuple_t<StructType, AliasType, JoinsType>;
|
||||
SelectFrom<TableOrQueryType, AliasType, FieldsType, JoinsType, Args...>> {
|
||||
using TableTupleType = table_tuple_t<TableOrQueryType, AliasType, JoinsType>;
|
||||
using Type = fields_to_named_tuple_t<TableTupleType, FieldsType>;
|
||||
};
|
||||
|
||||
template <class TableTupleType, class StructType, class AliasType,
|
||||
class FieldsType, class JoinsType, class WhereType, class GroupByType,
|
||||
template <class TableOrQueryType, class AliasType, class FieldsType,
|
||||
class JoinsType, class WhereType, class GroupByType,
|
||||
class OrderByType, class LimitType, class ToType>
|
||||
struct ToJoin<TableTupleType, SelectFrom<StructType, AliasType, FieldsType,
|
||||
JoinsType, WhereType, GroupByType,
|
||||
OrderByType, LimitType, ToType>> {
|
||||
template <class ConditionType, rfl::internal::StringLiteral _alias>
|
||||
dynamic::Join operator()(
|
||||
const transpilation::Join<
|
||||
SelectFrom<StructType, AliasType, FieldsType, JoinsType, WhereType,
|
||||
GroupByType, OrderByType, LimitType, ToType>,
|
||||
ConditionType, _alias>& _join) {
|
||||
const auto& query = _join.table_or_query;
|
||||
|
||||
using NestedTableTupleType =
|
||||
table_tuple_t<StructType, AliasType, JoinsType>;
|
||||
|
||||
return dynamic::Join{
|
||||
.how = _join.how,
|
||||
.table_or_query = Ref<dynamic::SelectFrom>::make(
|
||||
transpilation::to_select_from<NestedTableTupleType, AliasType,
|
||||
FieldsType, JoinsType, WhereType,
|
||||
GroupByType, OrderByType, LimitType>(
|
||||
query.fields_, query.joins_, query.where_, query.limit_)),
|
||||
.alias = Literal<_alias>().str(),
|
||||
.on = to_condition<TableTupleType>(_join.on)};
|
||||
struct ToTableOrQuery<
|
||||
SelectFrom<TableOrQueryType, AliasType, FieldsType, JoinsType, WhereType,
|
||||
GroupByType, OrderByType, LimitType, ToType>> {
|
||||
dynamic::SelectFrom::TableOrQueryType operator()(const auto& _query) {
|
||||
using TableTupleType =
|
||||
table_tuple_t<TableOrQueryType, AliasType, JoinsType>;
|
||||
return Ref<dynamic::SelectFrom>::make(
|
||||
transpilation::to_select_from<TableTupleType, AliasType, FieldsType,
|
||||
TableOrQueryType, JoinsType, WhereType,
|
||||
GroupByType, OrderByType, LimitType>(
|
||||
_query.fields_, _query.from_, _query.joins_, _query.where_,
|
||||
_query.limit_));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace transpilation
|
||||
|
||||
template <class StructType, class... FieldTypes>
|
||||
template <class TableType, class... FieldTypes>
|
||||
inline auto select_from(const FieldTypes&... _fields) {
|
||||
using FieldsType =
|
||||
rfl::Tuple<typename internal::GetColType<FieldTypes>::Type...>;
|
||||
return SelectFrom<StructType, Nothing, FieldsType>{
|
||||
return SelectFrom<transpilation::TableWrapper<TableType>, Nothing,
|
||||
FieldsType>{
|
||||
.fields_ =
|
||||
FieldsType(internal::GetColType<FieldTypes>::get_value(_fields)...)};
|
||||
FieldsType(internal::GetColType<FieldTypes>::get_value(_fields)...),
|
||||
.from_ = transpilation::TableWrapper<TableType>{}};
|
||||
}
|
||||
|
||||
template <class StructType, rfl::internal::StringLiteral _alias,
|
||||
template <class TableType, rfl::internal::StringLiteral _alias,
|
||||
class... FieldTypes>
|
||||
inline auto select_from(const FieldTypes&... _fields) {
|
||||
using FieldsType =
|
||||
rfl::Tuple<typename internal::GetColType<FieldTypes>::Type...>;
|
||||
return SelectFrom<StructType, Literal<_alias>, FieldsType>{
|
||||
return SelectFrom<transpilation::TableWrapper<TableType>, Literal<_alias>,
|
||||
FieldsType>{
|
||||
.fields_ =
|
||||
FieldsType(internal::GetColType<FieldTypes>::get_value(_fields)...)};
|
||||
FieldsType(internal::GetColType<FieldTypes>::get_value(_fields)...),
|
||||
.from_ = transpilation::TableWrapper<TableType>{}};
|
||||
}
|
||||
|
||||
template <rfl::internal::StringLiteral _alias, class QueryType,
|
||||
class... FieldTypes>
|
||||
inline auto select_from(const QueryType& _query, const FieldTypes&... _fields) {
|
||||
using FieldsType =
|
||||
rfl::Tuple<typename internal::GetColType<FieldTypes>::Type...>;
|
||||
return SelectFrom<QueryType, Literal<_alias>, FieldsType>{
|
||||
.fields_ =
|
||||
FieldsType(internal::GetColType<FieldTypes>::get_value(_fields)...),
|
||||
.from_ = _query};
|
||||
}
|
||||
|
||||
} // namespace sqlgen
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "../Literal.hpp"
|
||||
#include "../dynamic/JoinType.hpp"
|
||||
#include "TableWrapper.hpp"
|
||||
|
||||
namespace sqlgen::transpilation {
|
||||
|
||||
@@ -45,6 +46,11 @@ struct GetTableType<Literal<_alias>,
|
||||
"Alias could not be identified.");
|
||||
};
|
||||
|
||||
template <rfl::internal::StringLiteral _alias, class T>
|
||||
struct GetTableType<Literal<_alias>, TableWrapper<T>> {
|
||||
using TableType = T;
|
||||
};
|
||||
|
||||
template <rfl::internal::StringLiteral _alias, class T>
|
||||
struct GetTableType<Literal<_alias>, T> {
|
||||
using TableType = T;
|
||||
@@ -60,6 +66,11 @@ struct GetTableType<std::integral_constant<size_t, _i>,
|
||||
"Alias could not be identified.");
|
||||
};
|
||||
|
||||
template <size_t _i, class T>
|
||||
struct GetTableType<std::integral_constant<size_t, _i>, TableWrapper<T>> {
|
||||
using TableType = T;
|
||||
};
|
||||
|
||||
template <size_t _i, class T>
|
||||
struct GetTableType<std::integral_constant<size_t, _i>, T> {
|
||||
using TableType = T;
|
||||
|
||||
@@ -42,7 +42,7 @@ dynamic::SelectFrom read_to_select_from(const WhereType& _where = WhereType{},
|
||||
}));
|
||||
|
||||
return dynamic::SelectFrom{
|
||||
.table =
|
||||
.table_or_query =
|
||||
dynamic::Table{.name = get_tablename<T>(), .schema = get_schema<T>()},
|
||||
.fields = fields,
|
||||
.where = to_condition<std::remove_cvref_t<T>>(_where),
|
||||
|
||||
@@ -11,18 +11,18 @@
|
||||
|
||||
namespace sqlgen::transpilation {
|
||||
|
||||
template <class StructType, class AliasType, class JoinsType>
|
||||
template <class TableOrQueryType, class AliasType, class JoinsType>
|
||||
struct TableTupleType;
|
||||
|
||||
template <class StructType, class AliasType>
|
||||
struct TableTupleType<StructType, AliasType, Nothing> {
|
||||
using Type = StructType;
|
||||
template <class TableOrQueryType, class AliasType>
|
||||
struct TableTupleType<TableOrQueryType, AliasType, Nothing> {
|
||||
using Type = TableOrQueryType;
|
||||
};
|
||||
|
||||
template <class StructType, class AliasType, class... JoinTypes>
|
||||
struct TableTupleType<StructType, AliasType, rfl::Tuple<JoinTypes...>> {
|
||||
template <class TableOrQueryType, class AliasType, class... JoinTypes>
|
||||
struct TableTupleType<TableOrQueryType, AliasType, rfl::Tuple<JoinTypes...>> {
|
||||
using Type = rfl::Tuple<
|
||||
std::pair<extract_table_t<StructType>, AliasType>,
|
||||
std::pair<extract_table_t<TableOrQueryType>, AliasType>,
|
||||
std::pair<extract_table_t<typename JoinTypes::TableOrQueryType>,
|
||||
typename JoinTypes::Alias>...>;
|
||||
static_assert(
|
||||
@@ -30,9 +30,9 @@ struct TableTupleType<StructType, AliasType, rfl::Tuple<JoinTypes...>> {
|
||||
"Your SELECT FROM query cannot contain duplicate aliases.");
|
||||
};
|
||||
|
||||
template <class StructType, class AliasType, class JoinsType>
|
||||
template <class TableOrQueryType, class AliasType, class JoinsType>
|
||||
using table_tuple_t =
|
||||
typename TableTupleType<std::remove_cvref_t<StructType>,
|
||||
typename TableTupleType<std::remove_cvref_t<TableOrQueryType>,
|
||||
std::remove_cvref_t<AliasType>,
|
||||
std::remove_cvref_t<JoinsType>>::Type;
|
||||
|
||||
|
||||
@@ -19,6 +19,19 @@ namespace sqlgen::transpilation {
|
||||
template <class TableTupleType, class T>
|
||||
struct ToJoin;
|
||||
|
||||
template <class TableTupleType, class QueryType>
|
||||
struct ToJoin {
|
||||
template <class ConditionType, rfl::internal::StringLiteral _alias>
|
||||
dynamic::Join operator()(
|
||||
const transpilation::Join<QueryType, ConditionType, _alias>& _join) {
|
||||
return dynamic::Join{
|
||||
.how = _join.how,
|
||||
.table_or_query = to_table_or_query(_join.table_or_query),
|
||||
.alias = Literal<_alias>().str(),
|
||||
.on = to_condition<TableTupleType>(_join.on)};
|
||||
}
|
||||
};
|
||||
|
||||
template <class TableTupleType, class TableType>
|
||||
struct ToJoin<TableTupleType, TableWrapper<TableType>> {
|
||||
template <class ConditionType, rfl::internal::StringLiteral _alias>
|
||||
|
||||
@@ -15,11 +15,10 @@
|
||||
#include "../dynamic/Table.hpp"
|
||||
#include "../internal/collect/vector.hpp"
|
||||
#include "Join.hpp"
|
||||
#include "TableWrapper.hpp"
|
||||
#include "check_aggregations.hpp"
|
||||
#include "flatten_fields_t.hpp"
|
||||
#include "get_schema.hpp"
|
||||
#include "get_table_t.hpp"
|
||||
#include "get_tablename.hpp"
|
||||
#include "make_fields.hpp"
|
||||
#include "to_alias.hpp"
|
||||
#include "to_condition.hpp"
|
||||
@@ -27,13 +26,15 @@
|
||||
#include "to_joins.hpp"
|
||||
#include "to_limit.hpp"
|
||||
#include "to_order_by.hpp"
|
||||
#include "to_table_or_query.hpp"
|
||||
|
||||
namespace sqlgen::transpilation {
|
||||
|
||||
template <class TableTupleType, class AliasType, class FieldsType,
|
||||
class JoinsType, class WhereType, class GroupByType,
|
||||
class OrderByType, class LimitType>
|
||||
class TableOrQueryType, class JoinsType, class WhereType,
|
||||
class GroupByType, class OrderByType, class LimitType>
|
||||
dynamic::SelectFrom to_select_from(const FieldsType& _fields,
|
||||
const TableOrQueryType& _table_or_query,
|
||||
const JoinsType& _joins,
|
||||
const WhereType& _where,
|
||||
const LimitType& _limit) {
|
||||
@@ -43,17 +44,12 @@ dynamic::SelectFrom to_select_from(const FieldsType& _fields,
|
||||
"The aggregations were not set up correctly. Please check the "
|
||||
"trace for a more detailed error message.");
|
||||
|
||||
using StructType =
|
||||
get_table_t<std::integral_constant<size_t, 0>, TableTupleType>;
|
||||
|
||||
const auto fields = make_fields<TableTupleType, FieldsType>(
|
||||
_fields,
|
||||
std::make_integer_sequence<int, rfl::tuple_size_v<FieldsType>>());
|
||||
|
||||
return dynamic::SelectFrom{
|
||||
.table = dynamic::Table{.alias = to_alias<AliasType>(),
|
||||
.name = get_tablename<StructType>(),
|
||||
.schema = get_schema<StructType>()},
|
||||
.table_or_query = to_table_or_query(_table_or_query),
|
||||
.fields = fields,
|
||||
.alias = to_alias<AliasType>(),
|
||||
.joins = to_joins<TableTupleType>(_joins),
|
||||
|
||||
@@ -77,17 +77,20 @@ struct ToSQL<Read<ContainerType, WhereType, OrderByType, LimitType>> {
|
||||
}
|
||||
};
|
||||
|
||||
template <class StructType, class AliasType, class FieldsType, class JoinsType,
|
||||
class WhereType, class GroupByType, class OrderByType,
|
||||
class LimitType, class ToType>
|
||||
struct ToSQL<SelectFrom<StructType, AliasType, FieldsType, JoinsType, WhereType,
|
||||
GroupByType, OrderByType, LimitType, ToType>> {
|
||||
template <class TableOrQueryType, class AliasType, class FieldsType,
|
||||
class JoinsType, class WhereType, class GroupByType,
|
||||
class OrderByType, class LimitType, class ToType>
|
||||
struct ToSQL<
|
||||
SelectFrom<TableOrQueryType, AliasType, FieldsType, JoinsType, WhereType,
|
||||
GroupByType, OrderByType, LimitType, ToType>> {
|
||||
dynamic::Statement operator()(const auto& _select_from) const {
|
||||
using TableTupleType = table_tuple_t<StructType, AliasType, JoinsType>;
|
||||
return to_select_from<TableTupleType, AliasType, FieldsType, JoinsType,
|
||||
WhereType, GroupByType, OrderByType, LimitType>(
|
||||
_select_from.fields_, _select_from.joins_, _select_from.where_,
|
||||
_select_from.limit_);
|
||||
using TableTupleType =
|
||||
table_tuple_t<TableOrQueryType, AliasType, JoinsType>;
|
||||
return to_select_from<TableTupleType, AliasType, FieldsType,
|
||||
TableOrQueryType, JoinsType, WhereType, GroupByType,
|
||||
OrderByType, LimitType>(
|
||||
_select_from.fields_, _select_from.from_, _select_from.joins_,
|
||||
_select_from.where_, _select_from.limit_);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
34
include/sqlgen/transpilation/to_table_or_query.hpp
Normal file
34
include/sqlgen/transpilation/to_table_or_query.hpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef SQLGEN_TRANSPILATION_TO_TABLE_OR_QUERY_HPP_
|
||||
#define SQLGEN_TRANSPILATION_TO_TABLE_OR_QUERY_HPP_
|
||||
|
||||
#include <rfl.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
#include "../dynamic/SelectFrom.hpp"
|
||||
#include "../dynamic/Table.hpp"
|
||||
#include "TableWrapper.hpp"
|
||||
#include "get_schema.hpp"
|
||||
#include "get_tablename.hpp"
|
||||
|
||||
namespace sqlgen::transpilation {
|
||||
|
||||
template <class T>
|
||||
struct ToTableOrQuery;
|
||||
|
||||
template <class TableType>
|
||||
struct ToTableOrQuery<TableWrapper<TableType>> {
|
||||
dynamic::SelectFrom::TableOrQueryType operator()(const auto&) {
|
||||
using T = std::remove_cvref_t<TableType>;
|
||||
return dynamic::Table{.name = get_tablename<T>(),
|
||||
.schema = get_schema<T>()};
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
dynamic::SelectFrom::TableOrQueryType to_table_or_query(const T& _t) {
|
||||
return ToTableOrQuery<T>{}(_t);
|
||||
}
|
||||
|
||||
} // namespace sqlgen::transpilation
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user