Lightweight 0.20251201.0
Loading...
Searching...
No Matches
Update.hpp
1// SPDX-License-Identifier: Apache-2.0
2
3#pragma once
4
5#include "Core.hpp"
6
7#include <string>
8#include <string_view>
9#include <vector>
10
11namespace Lightweight
12{
13
14/// @brief Query builder for building UPDATE ... queries.
15///
16/// @ingroup QueryBuilder
17class [[nodiscard]] SqlUpdateQueryBuilder final: public SqlWhereClauseBuilder<SqlUpdateQueryBuilder>
18{
19 public:
20 /// Constructs a new SqlUpdateQueryBuilder object.
21 ///
22 /// @param formatter The SQL query formatter to use. One of SqlServerQueryFormatter, OracleSqlQueryFormatter,
23 /// PostgreSqlFormatter
24 /// @param table The name of the table to update.
25 /// @param tableAlias The alias of the table to update.
26 /// @param inputBindings The input bindings to use for the query.
27 SqlUpdateQueryBuilder(SqlQueryFormatter const& formatter,
28 std::string table,
29 std::string tableAlias,
30 std::vector<SqlVariant>* inputBindings) noexcept:
31 SqlWhereClauseBuilder<SqlUpdateQueryBuilder> {},
32 m_formatter { formatter }
33 {
34 m_searchCondition.tableName = std::move(table);
35 m_searchCondition.tableAlias = std::move(tableAlias);
36 m_searchCondition.inputBindings = inputBindings;
37 }
38
39 SqlSearchCondition& SearchCondition() noexcept // NOLINT(bugprone-derived-method-shadowing-base-method)
40 {
41 return m_searchCondition;
42 }
43
44 /// @brief Returns the SQL query formatter.
45 [[nodiscard]] SqlQueryFormatter const& FormatterLocal()
46 const noexcept // NOLINT(bugprone-derived-method-shadowing-base-method)
47 {
48 return m_formatter;
49 }
50
51 /// Adds a single column to the SET clause.
52 template <typename ColumnValue>
53 SqlUpdateQueryBuilder& Set(std::string_view columnName, ColumnValue const& value);
54
55 /// Adds a single column to the SET clause with the value being a string literal.
56 template <std::size_t N>
57 SqlUpdateQueryBuilder& Set(std::string_view columnName, char const (&value)[N]);
58
59 /// Finalizes building the query as UPDATE ... query.
60 [[nodiscard]] std::string ToSql() const;
61
62 private:
63 SqlQueryFormatter const& m_formatter;
64 std::string m_values;
65 SqlSearchCondition m_searchCondition;
66};
67
68template <typename ColumnValue>
69SqlUpdateQueryBuilder& SqlUpdateQueryBuilder::Set(std::string_view columnName, ColumnValue const& value)
70{
71 using namespace std::string_view_literals;
72
73 if (!m_values.empty())
74 m_values += ", "sv;
75
76 m_values += '"';
77 m_values += columnName;
78 m_values += R"(" = )"sv;
79
80 if constexpr (std::is_same_v<ColumnValue, SqlNullType>)
81 m_values += "NULL"sv;
82 else if constexpr (std::is_same_v<ColumnValue, SqlWildcardType>)
83 m_values += '?';
84 else if (m_searchCondition.inputBindings)
85 {
86 m_values += '?';
87 m_searchCondition.inputBindings->emplace_back(value);
88 }
89 else if constexpr (std::is_same_v<ColumnValue, char>)
90 m_values += m_formatter.StringLiteral(value);
91 else if constexpr (std::is_arithmetic_v<ColumnValue>)
92 m_values += std::format("{}", value);
93 else if constexpr (!WhereConditionLiteralType<ColumnValue>::needsQuotes)
94 m_values += std::format("{}", value);
95 else
96 {
97 m_values += '\'';
98 m_values += std::format("{}", value);
99 m_values += '\'';
100 }
101
102 return *this;
103}
104
105template <std::size_t N>
106SqlUpdateQueryBuilder& SqlUpdateQueryBuilder::Set(std::string_view columnName, char const (&value)[N])
107{
108 return Set(columnName, std::string_view { value, N - 1 });
109}
110
111inline LIGHTWEIGHT_FORCE_INLINE std::string SqlUpdateQueryBuilder::ToSql() const
112{
113 return m_formatter.Update(
114 m_searchCondition.tableName, m_searchCondition.tableAlias, m_values, m_searchCondition.condition);
115}
116
117} // namespace Lightweight