5#include "../SqlQueryFormatter.hpp"
9#include <reflection-cpp/reflection.hpp>
16enum class SqlQueryBuilderMode : uint8_t
22struct [[nodiscard]] SqlFieldExpression final
24 std::string expression;
30 inline SqlFieldExpression Count(std::string
const& field =
"*") noexcept
32 return SqlFieldExpression { .expression = std::format(
"COUNT(\"{}\")", field) };
35 inline SqlFieldExpression Count(SqlQualifiedTableColumnName
const& field)
noexcept
37 return SqlFieldExpression { .expression = std::format(R
"(COUNT("{}"."{}"))", field.tableName, field.columnName) };
40 inline SqlFieldExpression Sum(std::string
const& field)
noexcept
42 return SqlFieldExpression { .expression = std::format(
"SUM(\"{}\")", field) };
45 inline SqlFieldExpression Sum(SqlQualifiedTableColumnName
const& field)
noexcept
47 return SqlFieldExpression { .expression = std::format(R
"(SUM("{}"."{}"))", field.tableName, field.columnName) };
50 inline SqlFieldExpression Avg(std::string
const& field)
noexcept
52 return SqlFieldExpression { .expression = std::format(
"AVG(\"{}\")", field) };
55 inline SqlFieldExpression Avg(SqlQualifiedTableColumnName
const& field)
noexcept
57 return SqlFieldExpression { .expression = std::format(R
"(AVG("{}"."{}"))", field.tableName, field.columnName) };
60 inline SqlFieldExpression Min(std::string
const& field)
noexcept
62 return SqlFieldExpression { .expression = std::format(
"MIN(\"{}\")", field) };
65 inline SqlFieldExpression Min(SqlQualifiedTableColumnName
const& field)
noexcept
67 return SqlFieldExpression { .expression = std::format(R
"(MIN("{}"."{}"))", field.tableName, field.columnName) };
70 inline SqlFieldExpression Max(std::string
const& field)
noexcept
72 return SqlFieldExpression { .expression = std::format(
"MAX(\"{}\")", field) };
75 inline SqlFieldExpression Max(SqlQualifiedTableColumnName
const& field)
noexcept
77 return SqlFieldExpression { .expression = std::format(R
"(MAX("{}"."{}"))", field.tableName, field.columnName) };
89 using SelectType = detail::SelectType;
93 SqlBasicSelectQueryBuilder<SqlSelectQueryBuilder> {},
94 _formatter { formatter }
96 _query.formatter = &formatter;
97 _query.searchCondition.tableName = std::move(table);
98 _query.searchCondition.tableAlias = std::move(tableAlias);
99 _query.fields.reserve(256);
105 _mode = SqlQueryBuilderMode::Varying;
110 template <
typename... MoreFields>
130 std::string_view tableName);
134 std::string_view tableName);
143 template <
typename FirstRecord,
typename... MoreRecords>
147 [[deprecated(
"Use Field(...).As(\"alias\") instead.")]]
151 [[deprecated(
"Use Field(...).As(\"alias\") instead.")]]
153 std::string_view
const& alias);
156 template <
typename Callable>
160 LIGHTWEIGHT_API ComposedQuery
Count();
163 LIGHTWEIGHT_API ComposedQuery
All();
166 LIGHTWEIGHT_API ComposedQuery
First(
size_t count = 1);
169 LIGHTWEIGHT_API ComposedQuery
Range(std::size_t offset, std::size_t limit);
176 return _query.searchCondition;
189 SqlQueryBuilderMode _mode = SqlQueryBuilderMode::Fluent;
190 bool _aliasAllowed =
false;
193template <
typename... MoreFields>
196 using namespace std::string_view_literals;
198 std::ostringstream fragment;
200 if (!_query.fields.empty())
203 fragment <<
'"' << firstField <<
'"';
205 if constexpr (
sizeof...(MoreFields) > 0)
206 ((fragment << R
"(, ")"sv << std::forward<MoreFields>(moreFields) << '"') << ...);
208 _query.fields += fragment.str();
213template <
typename Callable>
221template <
typename FirstRecord,
typename... MoreRecords>
224 if constexpr (
sizeof...(MoreRecords) == 0)
226 Reflection::EnumerateMembers<FirstRecord>(
227 [&]<
size_t FieldIndex,
typename FieldType>() {
Field(FieldNameAt<FieldIndex, FirstRecord>); });
231 Reflection::EnumerateMembers<FirstRecord>([&]<
size_t FieldIndex,
typename FieldType>() {
233 .
tableName = RecordTableName<FirstRecord>,
234 .columnName = FieldNameAt<FieldIndex, FirstRecord>,
238 (Reflection::EnumerateMembers<MoreRecords>([&]<
size_t FieldIndex,
typename FieldType>() {
240 .
tableName = RecordTableName<MoreRecords>,
241 .columnName = FieldNameAt<FieldIndex, MoreRecords>,
Query builder for building SELECT ... queries.
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 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 SqlSelectQueryBuilder & Field(SqlQualifiedTableColumnName const &fieldName)
Adds a single column to the SELECT clause.
SqlSelectQueryBuilder(SqlQueryFormatter const &formatter, std::string table, std::string tableAlias) noexcept
Constructs a SELECT query builder.
SqlSelectQueryBuilder & Fields()
Adds a sequence of columns from the given tables to the SELECT clause.
LIGHTWEIGHT_API SqlSelectQueryBuilder & Fields(std::vector< std::string_view > const &fieldNames)
Adds a sequence of columns to the SELECT clause.
SqlSelectQueryBuilder & Build(Callable const &callable)
Builds the query using a callable.
LIGHTWEIGHT_API SqlSelectQueryBuilder & Fields(std::initializer_list< SqlQualifiedTableColumnName const > fieldNames)
Adds a sequence of qualified table column names 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 ComposedQuery All()
Finalizes building the query as SELECT field names FROM ... query.
LIGHTWEIGHT_API SqlSelectQueryBuilder & Field(SqlFieldExpression const &fieldExpression)
Adds an aggregate function call to the SELECT clause.
LIGHTWEIGHT_API SqlSelectQueryBuilder & FieldAs(SqlQualifiedTableColumnName const &fieldName, std::string_view const &alias)
Adds a single column with an alias to the SELECT clause.
LIGHTWEIGHT_FORCE_INLINE SqlQueryFormatter const & Formatter() const noexcept
Returns the SQL query formatter.
LIGHTWEIGHT_API ComposedQuery Count()
Finalizes building the query as SELECT COUNT(*) ... query.
LIGHTWEIGHT_FORCE_INLINE SqlSearchCondition & SearchCondition() noexcept
Returns the search condition for the query.
LIGHTWEIGHT_API SqlSelectQueryBuilder & Fields(std::span< SqlQualifiedTableColumnName const > fieldNames)
Adds a sequence of qualified table column names to the SELECT clause.
LIGHTWEIGHT_API SqlSelectQueryBuilder & As(std::string_view alias)
Aliases the last added field (a column or an aggregate call) in the SELECT clause.
constexpr LIGHTWEIGHT_FORCE_INLINE SqlSelectQueryBuilder & Varying() noexcept
Sets the builder mode to Varying, allowing varying final query types.
LIGHTWEIGHT_API SqlSelectQueryBuilder & Field(std::string_view const &fieldName)
Adds a single column to the SELECT clause.
LIGHTWEIGHT_API SqlSelectQueryBuilder & Fields(std::initializer_list< 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 Range(std::size_t offset, std::size_t limit)
Finalizes building the query as SELECT field names FROM ... query with a range.
Represents a single column in a table.
SqlQualifiedTableColumnName represents a column name qualified with a table name.
std::string_view tableName
The table name.