8e6a5deca6
Ref: https://github.com/rails/rails/pull/50793 To make not caching connection checkout viable, we need to reduced the amount of places where we need a connection. Once big source of this is query/relation building, where in many cases it eagerly quote and interpolation bound values in SQL fragments. Doing this requires an active connection because both MySQL and Postgres may quote values differently based on the connection settings. Instead of eagerly doing all this, we can instead just insert these as bound values in the Arel AST. For adapters with prepared statements this is better anyway as it will avoid leaking statements, and for those that don't support it, it will simply delay the quoting to just before the query is executed. However, the `%` API (`where("title = %s", something)`) can't realistically be fixed this way, but I don't see much value in it and it probably should be deprecated and removed.
50 lines
1007 B
Ruby
50 lines
1007 B
Ruby
# frozen_string_literal: true
|
|
|
|
module Arel # :nodoc: all
|
|
class UpdateManager < Arel::TreeManager
|
|
include TreeManager::StatementMethods
|
|
|
|
def initialize(table = nil)
|
|
@ast = Nodes::UpdateStatement.new(table)
|
|
end
|
|
|
|
###
|
|
# UPDATE +table+
|
|
def table(table)
|
|
@ast.relation = table
|
|
self
|
|
end
|
|
|
|
def set(values)
|
|
case values
|
|
when String, Nodes::BoundSqlLiteral
|
|
@ast.values = [values]
|
|
else
|
|
@ast.values = values.map { |column, value|
|
|
Nodes::Assignment.new(
|
|
Nodes::UnqualifiedColumn.new(column),
|
|
value
|
|
)
|
|
}
|
|
end
|
|
self
|
|
end
|
|
|
|
def group(columns)
|
|
columns.each do |column|
|
|
column = Nodes::SqlLiteral.new(column) if String === column
|
|
column = Nodes::SqlLiteral.new(column.to_s) if Symbol === column
|
|
|
|
@ast.groups.push Nodes::Group.new column
|
|
end
|
|
|
|
self
|
|
end
|
|
|
|
def having(expr)
|
|
@ast.havings << expr
|
|
self
|
|
end
|
|
end
|
|
end
|