Lightweight 0.20260617.0
Loading...
Searching...
No Matches
Select.hpp
1// SPDX-License-Identifier: Apache-2.0
2
3#pragma once
4
5#include "../SqlQueryFormatter.hpp"
6#include "../Utils.hpp"
7#include "Core.hpp"
8
9#include <reflection-cpp/reflection.hpp>
10
11#include <span>
12#include <utility>
13
14namespace Lightweight
15{
16
17enum class SqlQueryBuilderMode : uint8_t
18{
19 Fluent,
20 Varying
21};
22
23struct [[nodiscard]] SqlFieldExpression final
24{
25 std::string expression;
26};
27
28namespace Aggregate
29{
30
31 inline SqlFieldExpression Count(std::string_view field = "*") noexcept
32 {
33 if (field == "*")
34 return SqlFieldExpression { .expression = "COUNT(*)" };
35 return SqlFieldExpression { .expression = std::format("COUNT(\"{}\")", field) };
36 }
37
38 inline SqlFieldExpression Count(SqlQualifiedTableColumnName const& field) noexcept
39 {
40 if (field.columnName == "*")
41 return SqlFieldExpression { .expression = std::format(R"(COUNT("{}".*))", field.tableName) };
42 return SqlFieldExpression { .expression = std::format(R"(COUNT("{}"."{}"))", field.tableName, field.columnName) };
43 }
44
45 inline SqlFieldExpression Sum(std::string_view field) noexcept
46 {
47 return SqlFieldExpression { .expression = std::format("SUM(\"{}\")", field) };
48 }
49
50 inline SqlFieldExpression Sum(SqlQualifiedTableColumnName const& field) noexcept
51 {
52 return SqlFieldExpression { .expression = std::format(R"(SUM("{}"."{}"))", field.tableName, field.columnName) };
53 }
54
55 inline SqlFieldExpression Avg(std::string_view field) noexcept
56 {
57 return SqlFieldExpression { .expression = std::format("AVG(\"{}\")", field) };
58 }
59
60 inline SqlFieldExpression Avg(SqlQualifiedTableColumnName const& field) noexcept
61 {
62 return SqlFieldExpression { .expression = std::format(R"(AVG("{}"."{}"))", field.tableName, field.columnName) };
63 }
64
65 inline SqlFieldExpression Min(std::string_view field) noexcept
66 {
67 return SqlFieldExpression { .expression = std::format("MIN(\"{}\")", field) };
68 }
69
70 inline SqlFieldExpression Min(SqlQualifiedTableColumnName const& field) noexcept
71 {
72 return SqlFieldExpression { .expression = std::format(R"(MIN("{}"."{}"))", field.tableName, field.columnName) };
73 }
74
75 inline SqlFieldExpression Max(std::string_view field) noexcept
76 {
77 return SqlFieldExpression { .expression = std::format("MAX(\"{}\")", field) };
78 }
79
80 inline SqlFieldExpression Max(SqlQualifiedTableColumnName const& field) noexcept
81 {
82 return SqlFieldExpression { .expression = std::format(R"(MAX("{}"."{}"))", field.tableName, field.columnName) };
83 }
84
85} // namespace Aggregate
86
87/// @brief Query builder for building SELECT ... queries.
88///
89/// Not constructed directly by user code; obtained by adding a projection
90/// (`Field` / `Fields` / `FieldAs` / `Build`) to a @ref SqlSelectQueryStarter — the
91/// type returned by `SqlQueryBuilder::Select()`. The starter intentionally hides
92/// the finalizers @ref All, @ref First, and @ref Range so that an empty
93/// `Select().All()` (which would emit malformed `SELECT FROM "T"` SQL) fails at
94/// compile time; the gate is in the starter, not here.
95///
96/// @see SqlQueryBuilder
97/// @see SqlSelectQueryStarter
98class [[nodiscard]] SqlSelectQueryBuilder: public SqlBasicSelectQueryBuilder<SqlSelectQueryBuilder>
99{
100 public:
101 /// The select query type alias.
102 using SelectType = detail::SelectType;
103
104 /// Constructs a SELECT query builder.
105 explicit SqlSelectQueryBuilder(SqlQueryFormatter const& formatter, std::string table, std::string tableAlias) noexcept:
106 SqlBasicSelectQueryBuilder<SqlSelectQueryBuilder> {},
107 _formatter { formatter }
108 {
109 _query.formatter = &formatter;
110 _query.searchCondition.tableName = std::move(table);
111 _query.searchCondition.tableAlias = std::move(tableAlias);
112 _query.fields.reserve(256);
113 }
114
115 /// Sets the builder mode to Varying, allowing varying final query types.
116 constexpr LIGHTWEIGHT_FORCE_INLINE SqlSelectQueryBuilder& Varying() noexcept
117 {
118 _mode = SqlQueryBuilderMode::Varying;
119 return *this;
120 }
121
122 /// Adds a sequence of columns to the SELECT clause.
123 template <typename... MoreFields>
124 SqlSelectQueryBuilder& Fields(std::string_view const& firstField, MoreFields&&... moreFields);
125
126 /// Adds a single column to the SELECT clause.
127 LIGHTWEIGHT_API SqlSelectQueryBuilder& Field(std::string_view const& fieldName);
128
129 /// @copydoc Field(std::string_view const&)
130 /// Const overload: delegates via const_cast — see @ref Count() const.
131 [[nodiscard]] LIGHTWEIGHT_API SqlSelectQueryBuilder const& Field(std::string_view const& fieldName) const;
132
133 /// Adds a single column to the SELECT clause.
134 LIGHTWEIGHT_API SqlSelectQueryBuilder& Field(SqlQualifiedTableColumnName const& fieldName);
135
136 /// @copydoc Field(SqlQualifiedTableColumnName const&)
137 /// Const overload: delegates via const_cast — see @ref Count() const.
138 [[nodiscard]] LIGHTWEIGHT_API SqlSelectQueryBuilder const& Field(SqlQualifiedTableColumnName const& fieldName) const;
139
140 /// Adds an aggregate function call to the SELECT clause.
141 LIGHTWEIGHT_API SqlSelectQueryBuilder& Field(SqlFieldExpression const& fieldExpression);
142
143 /// @copydoc Field(SqlFieldExpression const&)
144 /// Const overload: delegates via const_cast — see @ref Count() const.
145 [[nodiscard]] LIGHTWEIGHT_API SqlSelectQueryBuilder const& Field(SqlFieldExpression const& fieldExpression) const;
146
147 /// Aliases the last added field (a column or an aggregate call) in the SELECT clause.
148 LIGHTWEIGHT_API SqlSelectQueryBuilder& As(std::string_view alias);
149
150 /// @copydoc As
151 /// Const overload: delegates via const_cast — see @ref Count() const.
152 [[nodiscard]] LIGHTWEIGHT_API SqlSelectQueryBuilder const& As(std::string_view alias) const;
153
154 /// Adds a sequence of columns to the SELECT clause.
155 LIGHTWEIGHT_API SqlSelectQueryBuilder& Fields(std::vector<std::string_view> const& fieldNames);
156
157 /// @copydoc Fields(std::vector<std::string_view> const&)
158 /// Const overload: delegates via const_cast — see @ref Count() const.
159 [[nodiscard]] LIGHTWEIGHT_API SqlSelectQueryBuilder const& Fields(std::vector<std::string_view> const& fieldNames) const;
160
161 /// Adds a sequence of columns from the given table to the SELECT clause.
162 LIGHTWEIGHT_API SqlSelectQueryBuilder& Fields(std::vector<std::string_view> const& fieldNames,
163 std::string_view tableName);
164
165 /// @copydoc Fields(std::vector<std::string_view> const&, std::string_view)
166 /// Const overload: delegates via const_cast — see @ref Count() const.
167 [[nodiscard]] LIGHTWEIGHT_API SqlSelectQueryBuilder const& Fields(std::vector<std::string_view> const& fieldNames,
168 std::string_view tableName) const;
169
170 /// Adds a sequence of columns from the given table to the SELECT clause.
171 LIGHTWEIGHT_API SqlSelectQueryBuilder& Fields(std::initializer_list<std::string_view> const& fieldNames,
172 std::string_view tableName);
173
174 /// @copydoc Fields(std::initializer_list<std::string_view> const&, std::string_view)
175 /// Const overload: delegates via const_cast — see @ref Count() const.
176 [[nodiscard]] LIGHTWEIGHT_API SqlSelectQueryBuilder const& Fields(
177 std::initializer_list<std::string_view> const& fieldNames, std::string_view tableName) const;
178
179 /// Adds a sequence of qualified table column names to the SELECT clause.
180 LIGHTWEIGHT_API SqlSelectQueryBuilder& Fields(std::span<SqlQualifiedTableColumnName const> fieldNames);
181
182 /// @copydoc Fields(std::span<SqlQualifiedTableColumnName const>)
183 /// Const overload: delegates via const_cast — see @ref Count() const.
184 [[nodiscard]] LIGHTWEIGHT_API SqlSelectQueryBuilder const& Fields(
185 std::span<SqlQualifiedTableColumnName const> fieldNames) const;
186
187 /// Adds a sequence of qualified table column names to the SELECT clause.
188 LIGHTWEIGHT_API SqlSelectQueryBuilder& Fields(std::initializer_list<SqlQualifiedTableColumnName const> fieldNames);
189
190 /// @copydoc Fields(std::initializer_list<SqlQualifiedTableColumnName const>)
191 /// Const overload: delegates via const_cast — see @ref Count() const.
192 [[nodiscard]] LIGHTWEIGHT_API SqlSelectQueryBuilder const& Fields(
193 std::initializer_list<SqlQualifiedTableColumnName const> fieldNames) const;
194
195 /// Adds a sequence of columns from the given tables to the SELECT clause.
196 template <typename FirstRecord, typename... MoreRecords>
198
199 /// Adds a single column with an alias to the SELECT clause.
200 [[deprecated("Use Field(...).As(\"alias\") instead.")]]
201 LIGHTWEIGHT_API SqlSelectQueryBuilder& FieldAs(std::string_view const& fieldName, std::string_view const& alias);
202
203 /// Adds a single column with an alias to the SELECT clause.
204 [[deprecated("Use Field(...).As(\"alias\") instead.")]]
206 std::string_view const& alias);
207
208 /// Builds the query using a callable.
209 template <typename Callable>
210 SqlSelectQueryBuilder& Build(Callable const& callable);
211
212 /// Finalizes building the query as SELECT COUNT(*) ... query.
213 LIGHTWEIGHT_API ComposedQuery Count();
214
215 /// @copydoc Count
216 /// Const overload: doesn't mutate @c *this — returns a snapshot ComposedQuery
217 /// so the finalizer can be reached through a `const SqlSelectQueryBuilder`.
218 [[nodiscard]] LIGHTWEIGHT_API ComposedQuery Count() const;
219
220 /// Finalizes building the query as SELECT field names FROM ... query.
221 LIGHTWEIGHT_API ComposedQuery All();
222
223 /// @copydoc All
224 /// Const overload: doesn't mutate @c *this — see @ref Count() const.
225 [[nodiscard]] LIGHTWEIGHT_API ComposedQuery All() const;
226
227 /// Finalizes building the query as SELECT TOP n field names FROM ... query.
228 LIGHTWEIGHT_API ComposedQuery First(size_t count = 1);
229
230 /// @copydoc First
231 /// Const overload: doesn't mutate @c *this — see @ref Count() const.
232 [[nodiscard]] LIGHTWEIGHT_API ComposedQuery First(size_t count = 1) const;
233
234 /// Finalizes building the query as SELECT field names FROM ... query with a range.
235 LIGHTWEIGHT_API ComposedQuery Range(std::size_t offset, std::size_t limit);
236
237 /// @copydoc Range
238 /// Const overload: doesn't mutate @c *this — see @ref Count() const.
239 [[nodiscard]] LIGHTWEIGHT_API ComposedQuery Range(std::size_t offset, std::size_t limit) const;
240
241 // clang-format off
242 /// Returns the search condition for the query.
243 LIGHTWEIGHT_FORCE_INLINE SqlSearchCondition& SearchCondition() noexcept // NOLINT(bugprone-derived-method-shadowing-base-method)
244 {
245 // clang-format on
246 return _query.searchCondition;
247 }
248
249 // clang-format off
250 /// Returns the SQL query formatter.
251 [[nodiscard]] LIGHTWEIGHT_FORCE_INLINE SqlQueryFormatter const& Formatter() const noexcept // NOLINT(bugprone-derived-method-shadowing-base-method)
252 {
253 // clang-format on
254 return _formatter;
255 }
256
257 private:
258 SqlQueryFormatter const& _formatter;
259 SqlQueryBuilderMode _mode = SqlQueryBuilderMode::Fluent;
260 // mutable: see the note on _query in SqlBasicSelectQueryBuilder — the alias
261 // flag is part of the projection accumulator, so it follows _query's policy.
262 // Marked mutable so the const-qualified Field/Fields/As overloads above can
263 // delegate to their non-const counterparts via const_cast.
264 mutable bool _aliasAllowed = false;
265};
266
267template <typename... MoreFields>
268SqlSelectQueryBuilder& SqlSelectQueryBuilder::Fields(std::string_view const& firstField, MoreFields&&... moreFields)
269{
270 using namespace std::string_view_literals;
271
272 std::ostringstream fragment;
273
274 if (!_query.fields.empty())
275 fragment << ", "sv;
276
277 fragment << '"' << firstField << '"';
278
279 if constexpr (sizeof...(MoreFields) > 0)
280 ((fragment << R"(, ")"sv << std::forward<MoreFields>(moreFields) << '"') << ...);
281
282 _query.fields += fragment.str();
283 return *this;
284}
285
286/// Builds the query using a callable.
287template <typename Callable>
288inline LIGHTWEIGHT_FORCE_INLINE SqlSelectQueryBuilder& SqlSelectQueryBuilder::Build(Callable const& callable)
289{
290 callable(*this);
291 return *this;
292}
293
294/// Adds fields from one or more record types to the SELECT clause.
295template <typename FirstRecord, typename... MoreRecords>
296inline LIGHTWEIGHT_FORCE_INLINE SqlSelectQueryBuilder& SqlSelectQueryBuilder::Fields()
297{
298 if constexpr (sizeof...(MoreRecords) == 0)
299 {
300 EnumerateRecordMembers<FirstRecord>(
301 [&]<size_t FieldIndex, typename FieldType>() { Field(FieldNameAt<FieldIndex, FirstRecord>); });
302 }
303 else
304 {
305 EnumerateRecordMembers<FirstRecord>([&]<size_t FieldIndex, typename FieldType>() {
307 .tableName = RecordTableName<FirstRecord>,
308 .columnName = FieldNameAt<FieldIndex, FirstRecord>,
309 });
310 });
311
312 (EnumerateRecordMembers<MoreRecords>([&]<size_t FieldIndex, typename FieldType>() {
314 .tableName = RecordTableName<MoreRecords>,
315 .columnName = FieldNameAt<FieldIndex, MoreRecords>,
316 });
317 }),
318 ...);
319 }
320 return *this;
321}
322
323namespace detail
324{
325 /// Always-false helper that depends on a template parameter so that a
326 /// @c static_assert in a function-template body only fires on instantiation
327 /// (and stays portable across compilers that have not implemented P2593).
328 template <typename...>
329 inline constexpr bool dependent_false = false;
330} // namespace detail
331
332/// @brief Compile-time gate for SELECT query construction.
333///
334/// Returned by `SqlQueryBuilder::Select()`. The starter inherits @em publicly
335/// from `SqlSelectQueryBuilder` (so every projection / WHERE / JOIN method
336/// resolves directly through inheritance), but defines its own @c All,
337/// @c First, and @c Range as deducing-this member templates whose bodies are
338/// ill-formed via @c static_assert. Those locals shadow the corresponding base
339/// methods at name lookup, so:
340///
341/// - `Select().All()`, `Select().First()`, `Select().Range(...)` — and the
342/// two-step variant `auto q = Select(); q.All();` — fail at compile time
343/// with a diagnostic asking the user to add a projection first. Without a
344/// projection these would emit malformed `SELECT FROM "T"` SQL.
345/// - `Select().Field(...).All()` compiles: `Field(...)` is inherited and
346/// returns `SqlSelectQueryBuilder&`, so the subsequent `All()` resolves
347/// against the base type (no shadowing) and reaches the real finalizer.
348/// - @c Count is intentionally not overridden — `SELECT COUNT(*) FROM ...`
349/// is well-formed without an explicit column list, so the inherited
350/// @c Count remains directly callable.
351/// - @c Distinct and @c Varying are overridden via deducing this so they
352/// return @c Self&& and the starter identity survives them. That keeps
353/// the gate intact for `Select().Distinct().All()` while still allowing
354/// `Select().Distinct().Fields(...).All()`.
355///
356/// Methods that conceptually follow the column list (@c Where, @c OrderBy,
357/// @c GroupBy, @c InnerJoin, @c LeftOuterJoin, etc.) are reachable on the
358/// starter through public inheritance and return `SqlSelectQueryBuilder&`,
359/// which technically lets `Select().WhereNotNull("x").All()` compile (a known
360/// gate leak the type primarily defends against the empty-`Select().All()`
361/// typo, which is far more common).
362///
363/// For the imperative loop pattern, capture the first projection as a builder
364/// reference and continue from there:
365///
366/// @code
367/// auto starter = qb.Select();
368/// auto& query = starter.Field(columns[0].name);
369/// for (size_t i = 1; i < columns.size(); ++i)
370/// query.Field(columns[i].name);
371/// return query.All();
372/// @endcode
373class [[nodiscard]] SqlSelectQueryStarter final: public SqlSelectQueryBuilder
374{
375 public:
376 /// Constructs a SELECT query starter.
377 ///
378 /// Intentionally not @c explicit so the factory in @ref SqlQueryBuilder::Select
379 /// can return via braced init.
380 SqlSelectQueryStarter(SqlQueryFormatter const& formatter, std::string table, std::string tableAlias) noexcept:
381 SqlSelectQueryBuilder { formatter, std::move(table), std::move(tableAlias) }
382 {
383 }
384
385 /// Empty-projection guard for the @c All finalizer.
386 ///
387 /// Instantiating this template emits a @c static_assert telling the caller
388 /// to add a projection first. Calling `All()` on a `SqlSelectQueryBuilder&`
389 /// returned by `Field(...)` / `Fields(...)` bypasses the shadow and reaches
390 /// the real `SqlSelectQueryBuilder::All()`.
391 template <typename Self>
392 auto All(this Self const& self) -> ComposedQuery
393 {
394 (void) self;
395 static_assert(detail::dependent_false<Self>,
396 "SELECT requires a projection. Call .Field(...) or .Fields(...) "
397 "before .All() — an empty projection produces malformed "
398 "`SELECT FROM \"T\"` SQL.");
399 std::unreachable();
400 }
401
402 /// Empty-projection guard for the @c First finalizer — see @ref All.
403 template <typename Self>
404 auto First(this Self const& self, size_t count = 1) -> ComposedQuery
405 {
406 (void) self;
407 (void) count;
408 static_assert(detail::dependent_false<Self>,
409 "SELECT requires a projection. Call .Field(...) or .Fields(...) "
410 "before .First().");
411 std::unreachable();
412 }
413
414 /// Empty-projection guard for the @c Range finalizer — see @ref All.
415 template <typename Self>
416 auto Range(this Self const& self, std::size_t offset, std::size_t limit) -> ComposedQuery
417 {
418 (void) self;
419 (void) offset;
420 (void) limit;
421 static_assert(detail::dependent_false<Self>,
422 "SELECT requires a projection. Call .Field(...) or .Fields(...) "
423 "before .Range().");
424 std::unreachable();
425 }
426
427 /// State-preserving override: returns @c Self&&, so the starter identity
428 /// survives the call and the @c All / @c First / @c Range guards above
429 /// keep their gate against `Select().Distinct().All()`.
430 template <typename Self>
431 LIGHTWEIGHT_FORCE_INLINE auto&& Distinct(this Self&& self) noexcept
432 {
433 self.SqlSelectQueryBuilder::Distinct();
434 return std::forward<Self>(self);
435 }
436
437 /// State-preserving override; see @ref Distinct.
438 template <typename Self>
439 LIGHTWEIGHT_FORCE_INLINE auto&& Varying(this Self&& self) noexcept
440 {
441 self.SqlSelectQueryBuilder::Varying();
442 return std::forward<Self>(self);
443 }
444};
445
446} // namespace Lightweight
API to format SQL queries for different SQL dialects.
Query builder for building SELECT ... queries.
Definition Select.hpp:99
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 const & Field(SqlQualifiedTableColumnName const &fieldName) const
Adds a single column to the SELECT clause.
LIGHTWEIGHT_API SqlSelectQueryBuilder & Field(SqlQualifiedTableColumnName const &fieldName)
Adds a single column to the SELECT clause.
LIGHTWEIGHT_API ComposedQuery First(size_t count=1) const
Finalizes building the query as SELECT TOP n field names FROM ... query.
LIGHTWEIGHT_API SqlSelectQueryBuilder const & Fields(std::vector< std::string_view > const &fieldNames) const
Adds a sequence of columns to the SELECT clause.
SqlSelectQueryBuilder(SqlQueryFormatter const &formatter, std::string table, std::string tableAlias) noexcept
Constructs a SELECT query builder.
Definition Select.hpp:105
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.
LIGHTWEIGHT_API SqlSelectQueryBuilder const & Fields(std::initializer_list< std::string_view > const &fieldNames, std::string_view tableName) const
Adds a sequence of columns from the given table 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() const
Finalizes building the query as SELECT field names FROM ... query.
LIGHTWEIGHT_API SqlSelectQueryBuilder const & Field(std::string_view const &fieldName) const
Adds a single column to the SELECT clause.
LIGHTWEIGHT_API ComposedQuery All()
Finalizes building the query as SELECT field names FROM ... query.
LIGHTWEIGHT_API SqlSelectQueryBuilder const & As(std::string_view alias) const
Aliases the last added field (a column or an aggregate call) in the SELECT clause.
LIGHTWEIGHT_API SqlSelectQueryBuilder & Field(SqlFieldExpression const &fieldExpression)
Adds an aggregate function call to the SELECT clause.
LIGHTWEIGHT_API ComposedQuery Range(std::size_t offset, std::size_t limit) const
Finalizes building the query as SELECT field names FROM ... query with a range.
LIGHTWEIGHT_API SqlSelectQueryBuilder & FieldAs(SqlQualifiedTableColumnName const &fieldName, std::string_view const &alias)
Adds a single column with an alias to the SELECT clause.
LIGHTWEIGHT_API SqlSelectQueryBuilder const & Fields(std::vector< std::string_view > const &fieldNames, std::string_view tableName) const
Adds a sequence of columns from the given table to the SELECT clause.
LIGHTWEIGHT_FORCE_INLINE SqlQueryFormatter const & Formatter() const noexcept
Returns the SQL query formatter.
Definition Select.hpp:251
LIGHTWEIGHT_API SqlSelectQueryBuilder const & Field(SqlFieldExpression const &fieldExpression) const
Adds an aggregate function call to the SELECT clause.
LIGHTWEIGHT_API SqlSelectQueryBuilder const & Fields(std::initializer_list< SqlQualifiedTableColumnName const > fieldNames) const
Adds a sequence of qualified table column names to the SELECT clause.
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.
Definition Select.hpp:243
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.
LIGHTWEIGHT_API SqlSelectQueryBuilder const & Fields(std::span< SqlQualifiedTableColumnName const > fieldNames) const
Adds a sequence of qualified table column names to the SELECT clause.
constexpr LIGHTWEIGHT_FORCE_INLINE SqlSelectQueryBuilder & Varying() noexcept
Sets the builder mode to Varying, allowing varying final query types.
Definition Select.hpp:116
LIGHTWEIGHT_API ComposedQuery Count() const
Finalizes building the query as SELECT COUNT(*) ... query.
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.
Compile-time gate for SELECT query construction.
Definition Select.hpp:374
SqlSelectQueryStarter(SqlQueryFormatter const &formatter, std::string table, std::string tableAlias) noexcept
Constructs a SELECT query starter.
Definition Select.hpp:380
auto All(this Self const &self) -> ComposedQuery
Empty-projection guard for the All finalizer.
Definition Select.hpp:392
LIGHTWEIGHT_FORCE_INLINE auto && Distinct(this Self &&self) noexcept
State-preserving override: returns Self&&, so the starter identity survives the call and the All / Fi...
Definition Select.hpp:431
LIGHTWEIGHT_FORCE_INLINE auto && Varying(this Self &&self) noexcept
State-preserving override; see Distinct.
Definition Select.hpp:439
auto Range(this Self const &self, std::size_t offset, std::size_t limit) -> ComposedQuery
Empty-projection guard for the Range finalizer — see All.
Definition Select.hpp:416
auto First(this Self const &self, size_t count=1) -> ComposedQuery
Empty-projection guard for the First finalizer — see All.
Definition Select.hpp:404
Represents a single column in a table.
Definition Field.hpp:84
SqlQualifiedTableColumnName represents a column name qualified with a table name.
Definition Utils.hpp:318
std::string_view tableName
The table name.
Definition Utils.hpp:320