Lightweight 0.20250904.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
40 {
41 return m_searchCondition;
42 }
43
44 /// @brief Returns the SQL query formatter.
45 [[nodiscard]] SqlQueryFormatter const& Formatter() const noexcept
46 {
47 return m_formatter;
48 }
49
50 /// Adds a single column to the SET clause.
51 template <typename ColumnValue>
52 SqlUpdateQueryBuilder& Set(std::string_view columnName, ColumnValue const& value);
53
54 /// Adds a single column to the SET clause with the value being a string literal.
55 template <std::size_t N>
56 SqlUpdateQueryBuilder& Set(std::string_view columnName, char const (&value)[N]);
57
58 /// Finalizes building the query as UPDATE ... query.
59 [[nodiscard]] std::string ToSql() const;
60
61 private:
62 SqlQueryFormatter const& m_formatter;
63 std::string m_values;
64 SqlSearchCondition m_searchCondition;
65};
66
67template <typename ColumnValue>
68SqlUpdateQueryBuilder& SqlUpdateQueryBuilder::Set(std::string_view columnName, ColumnValue const& value)
69{
70 using namespace std::string_view_literals;
71
72 if (!m_values.empty())
73 m_values += ", "sv;
74
75 m_values += '"';
76 m_values += columnName;
77 m_values += R"(" = )"sv;
78
79 if constexpr (std::is_same_v<ColumnValue, SqlNullType>)
80 m_values += "NULL"sv;
81 else if constexpr (std::is_same_v<ColumnValue, SqlWildcardType>)
82 m_values += '?';
83 else if (m_searchCondition.inputBindings)
84 {
85 m_values += '?';
86 m_searchCondition.inputBindings->emplace_back(value);
87 }
88 else if constexpr (std::is_same_v<ColumnValue, char>)
89 m_values += m_formatter.StringLiteral(value);
90 else if constexpr (std::is_arithmetic_v<ColumnValue>)
91 m_values += std::format("{}", value);
92 else if constexpr (!WhereConditionLiteralType<ColumnValue>::needsQuotes)
93 m_values += std::format("{}", value);
94 else
95 {
96 m_values += '\'';
97 m_values += std::format("{}", value);
98 m_values += '\'';
99 }
100
101 return *this;
102}
103
104template <std::size_t N>
105SqlUpdateQueryBuilder& SqlUpdateQueryBuilder::Set(std::string_view columnName, char const (&value)[N])
106{
107 return Set(columnName, std::string_view { value, N - 1 });
108}
109
110inline LIGHTWEIGHT_FORCE_INLINE std::string SqlUpdateQueryBuilder::ToSql() const
111{
112 return m_formatter.Update(
113 m_searchCondition.tableName, m_searchCondition.tableAlias, m_values, m_searchCondition.condition);
114}
115
116} // namespace Lightweight