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