23template <ColumnType Column, SqlExpr Value>
41template <TableType Table,
typename Sets = std::tuple<>,
typename Where = std::nullopt_t,
42 typename ReturningColumns = std::tuple<>>
48 ReturningColumns returning_columns_;
51 std::string returning_to_sql()
const {
52 if constexpr (is_empty_tuple<ReturningColumns>()) {
59 [&](
const auto&... cols) { ((ss << (i++ > 0 ?
", " :
"") << cols.to_sql()), ...); },
66 std::vector<std::string> returning_bind_params()
const {
67 std::vector<std::string> params;
69 if constexpr (!is_empty_tuple<ReturningColumns>()) {
71 [&](
const auto&... cols) {
72 auto process_col = [¶ms](
const auto& col) {
73 auto col_params = col.bind_params();
74 params.insert(params.end(), col_params.begin(), col_params.end());
77 (process_col(cols), ...);
97 ReturningColumns returning_columns = {})
98 : table_(
std::move(table)), sets_(
std::move(sets)), where_(
std::move(
where)),
99 returning_columns_(
std::move(returning_columns)) {}
104 std::stringstream ss;
105 ss <<
"UPDATE " << table_.table_name;
108 if constexpr (!is_empty_tuple<Sets>()) {
114 if constexpr (!std::is_same_v<Where, std::nullopt_t>) {
115 if (where_.has_value()) {
116 ss <<
" WHERE " << where_.value().to_sql();
121 ss << returning_to_sql();
129 std::vector<std::string> params;
132 if constexpr (!is_empty_tuple<Sets>()) {
134 params.insert(params.end(), set_params.begin(), set_params.end());
138 if constexpr (!std::is_same_v<Where, std::nullopt_t>) {
139 if (where_.has_value()) {
140 auto where_params = where_.value().bind_params();
141 params.insert(params.end(), where_params.begin(), where_params.end());
146 auto returning_params = returning_bind_params();
147 params.insert(params.end(), returning_params.begin(), returning_params.end());
158 template <ColumnType Col, SqlExpr Val>
164 auto set_item = SetItemType(col_ref, std::forward<Val>(
val));
167 auto new_item_tuple = std::make_tuple(std::move(set_item));
170 auto new_sets = std::tuple_cat(sets_, std::move(new_item_tuple));
174 table_, std::move(new_sets), where_, returning_columns_);
183 template <ColumnType Col,
typename T>
190 auto value_expr =
value(std::forward<T>(
val));
191 return set(
column, std::move(value_expr));
198 template <ConditionExpr Condition>
199 auto where(
const Condition& cond)
const {
201 table_, sets_, std::optional<Condition>(cond), returning_columns_);
210 template <ColumnType Col, std::ranges::range Range>
211 requires std::convertible_to<std::ranges::range_value_t<Range>, std::string>
214 auto in_condition =
in(col_expr, values);
215 return where(in_condition);
222 template <
typename... Args>
225 auto to_expr = [](
const auto& arg) {
226 if constexpr (
SqlExpr<std::remove_cvref_t<
decltype(arg)>>) {
228 }
else if constexpr (
ColumnType<std::remove_cvref_t<
decltype(arg)>>) {
231 static_assert(
SqlExpr<std::remove_cvref_t<
decltype(arg)>> ||
232 ColumnType<std::remove_cvref_t<
decltype(arg)>>,
233 "Arguments to returning() must be either columns or SQL expressions");
239 using ReturningTuple = std::tuple<decltype(to_expr(std::declval<Args>()))...>;
240 auto returning_tuple = std::make_tuple(
to_expr(args)...);
243 std::move(returning_tuple));
251template <TableType Table>
Column reference expression.
Base UPDATE query builder.
std::string to_sql() const
Generate the SQL for this UPDATE query.
ReturningColumns returning_columns_type
auto set(const Col &column, Val &&val) const
Add or replace a SET clause assignment.
auto where(const Condition &cond) const
Add a WHERE clause to the query.
auto where_in(const Col &column, const Range &values) const
Set a condition for filtering the rows to update using IN with values.
auto returning(const Args &... args) const
Specify columns to return after update.
UpdateQuery(Table table, Sets sets={}, Where where=std::nullopt, ReturningColumns returning_columns={})
Constructor for the UPDATE query builder.
std::vector< std::string > bind_params() const
Get the bind parameters for this UPDATE query.
auto set(const Col &column, T &&val) const
Add or replace a SET clause assignment with a raw value (with type checking)
Represents a literal value in a SQL query.
std::vector< std::string > bind_params() const override
std::string to_sql() const override
Represents a column in a database table.
Concept for column types.
Concept for SQL expression components.
std::string tuple_to_sql(const Tuple &tuple, const char *separator)
Helper to convert a tuple of expressions to SQL.
auto in(const schema::column< TableT, Name, T, Modifiers... > &col, Range values)
Create an IN condition with type checking for columns.
auto column_ref(const Column &col)
Create a column reference expression.
auto update(const Table &table)
Create an UPDATE query for the specified table.
auto to_expr(const C &col, std::string_view table_name="")
Helper to wrap a schema column in a SQL expression.
auto value(T val)
Create a value expression.
std::vector< std::string > tuple_bind_params(const Tuple &tuple)
Helper to collect bind parameters from a tuple of expressions.
auto val(const char *str)
Helper to create a value expression from a string literal.
Represents a SET clause assignment in an UPDATE statement.
std::string to_sql() const
ColumnRef< Column > column
std::vector< std::string > bind_params() const
SetItem(ColumnRef< Column > col, Value val)