5#include "../SqlQueryFormatter.hpp"
9#include <reflection-cpp/reflection.hpp>
11enum class SqlQueryBuilderMode : uint8_t
17struct [[nodiscard]] SqlFieldExpression final
19 std::string expression;
25inline SqlFieldExpression Count(std::string
const& field =
"*") noexcept
27 return SqlFieldExpression { .expression = std::format(
"COUNT(\"{}\")", field) };
32 return SqlFieldExpression { .expression = std::format(R
"(COUNT("{}"."{}"))", field.tableName, field.columnName) };
35inline SqlFieldExpression Sum(std::string
const& field)
noexcept
37 return SqlFieldExpression { .expression = std::format(
"SUM(\"{}\")", field) };
42 return SqlFieldExpression { .expression = std::format(R
"(SUM("{}"."{}"))", field.tableName, field.columnName) };
45inline SqlFieldExpression Avg(std::string
const& field)
noexcept
47 return SqlFieldExpression { .expression = std::format(
"AVG(\"{}\")", field) };
52 return SqlFieldExpression { .expression = std::format(R
"(AVG("{}"."{}"))", field.tableName, field.columnName) };
55inline SqlFieldExpression Min(std::string
const& field)
noexcept
57 return SqlFieldExpression { .expression = std::format(
"MIN(\"{}\")", field) };
62 return SqlFieldExpression { .expression = std::format(R
"(MIN("{}"."{}"))", field.tableName, field.columnName) };
65inline SqlFieldExpression Max(std::string
const& field)
noexcept
67 return SqlFieldExpression { .expression = std::format(
"MAX(\"{}\")", field) };
72 return SqlFieldExpression { .expression = std::format(R
"(MAX("{}"."{}"))", field.tableName, field.columnName) };
83 using SelectType = detail::SelectType;
86 SqlBasicSelectQueryBuilder<SqlSelectQueryBuilder> {},
87 _formatter { formatter }
89 _query.formatter = &formatter;
90 _query.searchCondition.tableName = std::move(table);
91 _query.searchCondition.tableAlias = std::move(tableAlias);
92 _query.fields.reserve(256);
98 _mode = SqlQueryBuilderMode::Varying;
103 template <
typename... MoreFields>
123 std::string_view tableName);
125 LIGHTWEIGHT_API
SqlSelectQueryBuilder& Fields(std::initializer_list<std::string_view>
const& fieldNames,
126 std::string_view tableName);
129 template <
typename FirstRecord,
typename... MoreRecords>
133 [[deprecated(
"Use Field(...).As(\"alias\") instead.")]]
137 [[deprecated(
"Use Field(...).As(\"alias\") instead.")]]
139 std::string_view
const& alias);
141 template <
typename Callable>
145 LIGHTWEIGHT_API ComposedQuery
Count();
148 LIGHTWEIGHT_API ComposedQuery
All();
151 LIGHTWEIGHT_API ComposedQuery
First(
size_t count = 1);
154 LIGHTWEIGHT_API ComposedQuery
Range(std::size_t offset, std::size_t limit);
156 LIGHTWEIGHT_FORCE_INLINE SqlSearchCondition& SearchCondition() noexcept
158 return _query.searchCondition;
161 [[nodiscard]] LIGHTWEIGHT_FORCE_INLINE
SqlQueryFormatter const& Formatter() const noexcept
168 SqlQueryBuilderMode _mode = SqlQueryBuilderMode::Fluent;
169 bool _aliasAllowed =
false;
172template <
typename... MoreFields>
175 using namespace std::string_view_literals;
177 std::ostringstream fragment;
179 if (!_query.fields.empty())
182 fragment <<
'"' << firstField <<
'"';
184 if constexpr (
sizeof...(MoreFields) > 0)
185 ((fragment << R
"(, ")"sv << std::forward<MoreFields>(moreFields) << '"') << ...);
187 _query.fields += fragment.str();
191template <
typename Callable>
192inline LIGHTWEIGHT_FORCE_INLINE
SqlSelectQueryBuilder& SqlSelectQueryBuilder::Build(Callable
const& callable)
198template <
typename FirstRecord,
typename... MoreRecords>
201 if constexpr (
sizeof...(MoreRecords) == 0)
203 Reflection::EnumerateMembers<FirstRecord>(
204 [&]<
size_t FieldIndex,
typename FieldType>() {
Field(FieldNameAt<FieldIndex, FirstRecord>); });
208 Reflection::EnumerateMembers<FirstRecord>([&]<
size_t FieldIndex,
typename FieldType>() {
210 .tableName = RecordTableName<FirstRecord>,
211 .columnName = FieldNameAt<FieldIndex, FirstRecord>,
215 (Reflection::EnumerateMembers<MoreRecords>([&]<
size_t FieldIndex,
typename FieldType>() {
217 .tableName = RecordTableName<MoreRecords>,
218 .columnName = FieldNameAt<FieldIndex, MoreRecords>,
Query builder for building SELECT ... queries.
LIGHTWEIGHT_API SqlSelectQueryBuilder & Fields(std::vector< std::string_view > const &fieldNames, std::string_view tableName)
Adds a sequence of columns from the given table to the SELECT clause.
LIGHTWEIGHT_API ComposedQuery Count()
Finalizes building the query as SELECT COUNT(*) ... query.
LIGHTWEIGHT_API SqlSelectQueryBuilder & As(std::string_view alias)
Aliases the last added field (a column or an aggregate call) in the SELECT clause.
LIGHTWEIGHT_API SqlSelectQueryBuilder & Fields(std::vector< std::string_view > const &fieldNames)
Adds a sequence of columns to the SELECT clause.
LIGHTWEIGHT_API SqlSelectQueryBuilder & Field(SqlQualifiedTableColumnName const &fieldName)
Adds a single column to the SELECT clause.
LIGHTWEIGHT_API SqlSelectQueryBuilder & FieldAs(std::string_view const &fieldName, std::string_view const &alias)
Adds a single column with an alias to the SELECT clause.
LIGHTWEIGHT_API ComposedQuery Range(std::size_t offset, std::size_t limit)
Finalizes building the query as SELECT field names FROM ... query with a range.
constexpr LIGHTWEIGHT_FORCE_INLINE SqlSelectQueryBuilder & Varying() noexcept
Sets the builder mode to Varying, allowing varying final query types.
LIGHTWEIGHT_API ComposedQuery All()
Finalizes building the query as SELECT field names FROM ... query.
LIGHTWEIGHT_API SqlSelectQueryBuilder & Field(std::string_view const &fieldName)
Adds a single column to the SELECT clause.
LIGHTWEIGHT_API SqlSelectQueryBuilder & Field(SqlFieldExpression const &fieldExpression)
Adds an aggregate function call to the SELECT clause.
SqlSelectQueryBuilder & Fields()
Adds a sequence of columns from the given tables to the SELECT clause.
LIGHTWEIGHT_API ComposedQuery First(size_t count=1)
Finalizes building the query as SELECT TOP n field names FROM ... query.
LIGHTWEIGHT_API SqlSelectQueryBuilder & FieldAs(SqlQualifiedTableColumnName const &fieldName, std::string_view const &alias)
Adds a single column with an alias to the SELECT clause.
Represents a single column in a table.
SqlQualifiedTableColumnName represents a column name qualified with a table name.