Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't mutate the query builder when calling the statement methods #715

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions spec/query_builder_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@ describe Avram::QueryBuilder do
query.args.should eq ["Paul", "20"]
end

it "has the same statement on subsequent calls" do
query = new_query
.where(Avram::Where::Equal.new(:name, "Paul"))
.where(Avram::Where::GreaterThan.new(:age, "20"))
query.statement.should eq "SELECT * FROM users WHERE name = $1 AND age > $2"
query.statement.should eq "SELECT * FROM users WHERE name = $1 AND age > $2"
end

it "accepts raw where clauses" do
query = new_query
.where(Avram::Where::Raw.new("name = ?", "Mikias"))
Expand Down Expand Up @@ -132,6 +140,16 @@ describe Avram::QueryBuilder do
query.statement_for_update(params).should eq "UPDATE users SET first_name = $1, last_name = $2 WHERE id = $3 LIMIT 1 RETURNING *"
query.args_for_update(params).should eq ["Paul", nil, "1"]
end

it "has the same placeholder values on subsequent calls" do
params = {:first_name => "Paul", :last_name => nil}
query = new_query
.where(Avram::Where::Equal.new(:id, "1"))
.limit(1)

query.statement_for_update(params).should eq "UPDATE users SET first_name = $1, last_name = $2 WHERE id = $3 LIMIT 1 RETURNING *"
query.statement_for_update(params).should eq "UPDATE users SET first_name = $1, last_name = $2 WHERE id = $3 LIMIT 1 RETURNING *"
end
end

it "can be counted" do
Expand Down
14 changes: 8 additions & 6 deletions src/avram/query_builder.cr
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,18 @@ class Avram::QueryBuilder
end

def statement
clone.statement!
end

def statement!
join_sql [@delete ? delete_sql : select_sql] + sql_condition_clauses
end

def statement_for_update(params, return_columns returning? : Bool = true)
clone.statement_for_update!(params, returning?)
end

def statement_for_update!(params, return_columns returning? : Bool = true)
sql = ["UPDATE #{table}", set_sql_clause(params)]
sql += sql_condition_clauses
sql += ["RETURNING #{@selections}"] if returning?
Expand Down Expand Up @@ -316,13 +324,7 @@ class Avram::QueryBuilder
@wheres.pop
end

@_wheres_sql : String?

private def wheres_sql
@_wheres_sql ||= joined_wheres_queries
end

private def joined_wheres_queries
if !wheres.empty?
statements = wheres.flat_map do |sql_clause|
clause = sql_clause.prepare(->next_prepared_statement_placeholder)
Expand Down