Skip to content

Commit

Permalink
fix(bug): allow "complex" filter with update statement
Browse files Browse the repository at this point in the history
  • Loading branch information
bunnylushington committed May 13, 2024
1 parent 717d191 commit 6e0c555
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 26 deletions.
32 changes: 9 additions & 23 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 ->
{"#{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
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)

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
34 changes: 31 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,13 +35,40 @@ 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

# test "it actually works" do
Expand Down

0 comments on commit 6e0c555

Please sign in to comment.