Skip to content

Commit

Permalink
Merge pull request #119 from bunnylushington/fix/update-with-in-filter
Browse files Browse the repository at this point in the history
fix(bug): allow "complex" filter with update statement
  • Loading branch information
cpursley authored May 14, 2024
2 parents 717d191 + 972b860 commit 3bfed53
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 23 deletions.
26 changes: 6 additions & 20 deletions lib/moebius/query.ex
Original file line number Diff line number Diff line change
Expand Up @@ -432,31 +432,17 @@ defmodule Moebius.Query do
cols = Keyword.keys(criteria)
vals = Keyword.values(criteria)

{cols, col_count} =
Enum.map_reduce(cols, 1, fn col, acc ->
first_available_param = length(cmd.params) + 1

{cols, _col_count} =
Enum.map_reduce(cols, first_available_param, fn col, acc ->
{"#{col} = $#{acc}", acc + 1}
end)

# here's something for John to clean up :):)
where =
cond do
length(cmd.where_columns) > 0 ->
{filters, _count} =
Enum.map_reduce(cmd.where_columns, col_count, fn col, acc ->
{"#{col} = $#{acc}", acc + 1}
end)

" where " <> Enum.join(filters, " and ")

cmd.where ->
cmd.where
end

# add the filter criteria to the update list
params = vals ++ cmd.params
params = cmd.params ++ vals
columns = Enum.join(cols, ", ")

sql = "update #{cmd.table_name} set #{columns}#{where} returning *;"
sql = "update #{cmd.table_name} set #{columns}#{cmd.where} returning *;"
%{cmd | sql: sql, type: :update, params: params}
end

Expand Down
32 changes: 29 additions & 3 deletions test/moebius/update_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ defmodule Moebius.UpdateTest do
end

test "a basic user update", %{cmd: cmd} do
assert cmd.sql == "update users set email = $1 where id = $2 returning *;"
assert cmd.sql == "update users set email = $2 where id = $1 returning *;"
assert length(cmd.params) == 2
assert cmd.params == [1, "[email protected]"]
end

test "a basic user insert has params set", %{cmd: cmd} do
Expand All @@ -34,11 +35,36 @@ defmodule Moebius.UpdateTest do
test "a bulk update with a string filter and params" do
cmd =
db(:users)
|> filter("email LIKE %$2", "test")
|> filter("email LIKE %$1", "test")
|> update(email: "[email protected]")

assert cmd.sql == "update users set email = $1 where email LIKE %$2 returning *;"
assert cmd.sql == "update users set email = $2 where email LIKE %$1 returning *;"
assert length(cmd.params) == 2
assert cmd.params == ["test", "[email protected]"]
end

test "basic update with 'in' filter" do
names = ["Super", "Mike"]

cmd =
db(:users)
|> filter(:first, in: names)
|> update(roles: ["newrole"])

assert cmd.sql == "update users set roles = $3 where first IN($1, $2) returning *;"
assert length(cmd.params) == 3
assert cmd.params == names ++ [["newrole"]]
end

test "basic update with '>' filter" do
cmd =
db(:users)
|> filter(:order_count, gt: 5)
|> update(roles: ["newrole"])

assert cmd.sql == "update users set roles = $2 where order_count > $1 returning *;"
assert length(cmd.params) == 2
assert cmd.params == [5, ["newrole"]]
end

# TODO: Move this to date tests
Expand Down

0 comments on commit 3bfed53

Please sign in to comment.