Skip to content

Commit ed42ff3

Browse files
author
Michael Maier
committed
replaced op_update by update command
1 parent 364c682 commit ed42ff3

File tree

3 files changed

+42
-77
lines changed

3 files changed

+42
-77
lines changed

lib/mongo.ex

Lines changed: 40 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,7 @@ defmodule Mongo do
695695
# This is the implementation of the delete command for
696696
# delete_one and delete_many
697697
#
698-
defp delete_documents(topology_pid, coll, filter, limit, opts \\ []) do
698+
defp delete_documents(topology_pid, coll, filter, limit, opts) do
699699

700700
# see https://docs.mongodb.com/manual/reference/command/delete/#dbcmd.delete
701701
write_concern = %{
@@ -749,20 +749,7 @@ defmodule Mongo do
749749
@spec replace_one(GenServer.server, collection, BSON.document, BSON.document, Keyword.t) :: result(Mongo.UpdateResult.t)
750750
def replace_one(topology_pid, coll, filter, replacement, opts \\ []) do
751751
_ = modifier_docs(replacement, :replace)
752-
753-
params = [filter, replacement]
754-
query = %Query{action: :replace_one, extra: coll}
755-
with {:ok, conn, _, _} <- select_server(topology_pid, :write, opts),
756-
{:ok, reply} <- DBConnection.execute(conn, query, params, defaults(opts)),
757-
:ok <- maybe_failure(reply),
758-
{:ok, doc} <- get_last_error(reply) do
759-
case doc do
760-
%{"n" => 1, "upserted" => upserted_id} ->
761-
{:ok, %Mongo.UpdateResult{matched_count: 0, modified_count: 1, upserted_id: upserted_id}}
762-
%{"n" => n} ->
763-
{:ok, %Mongo.UpdateResult{matched_count: n, modified_count: n}}
764-
end
765-
end
752+
update_documents(topology_pid, coll, filter, replacement, false, opts)
766753
end
767754

768755
@doc """
@@ -795,20 +782,7 @@ defmodule Mongo do
795782
@spec update_one(GenServer.server, collection, BSON.document, BSON.document, Keyword.t) :: result(Mongo.UpdateResult.t)
796783
def update_one(topology_pid, coll, filter, update, opts \\ []) do
797784
_ = modifier_docs(update, :update)
798-
799-
params = [filter, update]
800-
query = %Query{action: :update_one, extra: coll}
801-
with {:ok, conn, _, _} <- select_server(topology_pid, :write, opts),
802-
{:ok, reply} <- DBConnection.execute(conn, query, params, defaults(opts)),
803-
:ok <- maybe_failure(reply),
804-
{:ok, doc} <- get_last_error(reply) do
805-
case doc do
806-
%{"n" => 1, "upserted" => upserted_id} ->
807-
{:ok, %Mongo.UpdateResult{matched_count: 0, modified_count: 1, upserted_id: upserted_id}}
808-
%{"n" => n} ->
809-
{:ok, %Mongo.UpdateResult{matched_count: n, modified_count: n}}
810-
end
811-
end
785+
update_documents(topology_pid, coll, filter, update, false, opts)
812786
end
813787

814788
@doc """
@@ -834,18 +808,46 @@ defmodule Mongo do
834808
@spec update_many(GenServer.server, collection, BSON.document, BSON.document, Keyword.t) :: result(Mongo.UpdateResult.t)
835809
def update_many(topology_pid, coll, filter, update, opts \\ []) do
836810
_ = modifier_docs(update, :update)
811+
update_documents(topology_pid, coll, filter, update, true, opts)
812+
end
813+
814+
defp update_documents(topology_pid, coll, filter, update, multi, opts) do
815+
816+
# see https://docs.mongodb.com/manual/reference/command/update/#update-command-output
817+
# validation of the update document
818+
write_concern = %{
819+
w: Keyword.get(opts, :w),
820+
j: Keyword.get(opts, :j),
821+
wtimeout: Keyword.get(opts, :wtimeout)
822+
} |> filter_nils()
823+
824+
update = %{
825+
q: filter,
826+
u: update,
827+
upsert: Keyword.get(opts, :upsert),
828+
multi: multi,
829+
collation: Keyword.get(opts, :ordered),
830+
arrayFilters: Keyword.get(opts, :filters)
831+
} |> filter_nils()
832+
833+
query = [
834+
update: coll,
835+
updates: [update],
836+
ordered: Keyword.get(opts, :ordered),
837+
writeConcern: write_concern,
838+
bypassDocumentValidation: Keyword.get(opts, :bypass_document_validation)
839+
] |> filter_nils()
837840

838-
params = [filter, update]
839-
query = %Query{action: :update_many, extra: coll}
840841
with {:ok, conn, _, _} <- select_server(topology_pid, :write, opts),
841-
{:ok, reply} <- DBConnection.execute(conn, query, params, defaults(opts)),
842-
:ok <- maybe_failure(reply),
843-
{:ok, doc} <- get_last_error(reply) do
842+
{:ok, doc} <- direct_command(conn, query, opts) do
844843
case doc do
845-
%{"n" => 1, "upserted" => upserted_id} ->
846-
{:ok, %Mongo.UpdateResult{matched_count: 0, modified_count: 1, upserted_id: upserted_id}}
847-
%{"n" => n} ->
848-
{:ok, %Mongo.UpdateResult{matched_count: n, modified_count: n}}
844+
# todo: better handling off the result
845+
%{"writeErrors" => _} -> {:error, %Mongo.WriteError{n: doc["n"], ok: doc["ok"], write_errors: doc["writeErrors"]}}
846+
%{"n" => n, "nModified" => n_modified} ->
847+
case Map.get(write_concern, :w) do
848+
0 -> {:ok, %Mongo.UpdateResult{acknowledged: false}}
849+
_ -> {:ok, %Mongo.UpdateResult{matched_count: n, modified_count: n_modified}}
850+
end
849851
end
850852
end
851853
end

lib/mongo/mongo_db_connection.ex

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ defmodule Mongo.MongoDBConnection do
99

1010
@timeout 5000
1111
@find_one_flags ~w(slave_ok exhaust partial)a
12-
@update_flags ~w(upsert)a
1312
@write_concern ~w(w j wtimeout)a
1413

1514
def connect(opts) do
@@ -144,27 +143,6 @@ defmodule Mongo.MongoDBConnection do
144143
{:ok, state.wire_version, state}
145144
end
146145

147-
defp handle_execute(:replace_one, coll, [query, replacement], opts, s) do
148-
flags = flags(Keyword.take(opts, @update_flags))
149-
op = op_update(coll: Utils.namespace(coll, s, opts[:database]), query: query, update: replacement,
150-
flags: flags)
151-
message_gle(-15, op, opts, s)
152-
end
153-
154-
defp handle_execute(:update_one, coll, [query, update], opts, s) do
155-
flags = flags(Keyword.take(opts, @update_flags))
156-
op = op_update(coll: Utils.namespace(coll, s, opts[:database]), query: query, update: update,
157-
flags: flags)
158-
message_gle(-16, op, opts, s)
159-
end
160-
161-
defp handle_execute(:update_many, coll, [query, update], opts, s) do
162-
flags = [:multi | flags(Keyword.take(opts, @update_flags))]
163-
op = op_update(coll: Utils.namespace(coll, s, opts[:database]), query: query, update: update,
164-
flags: flags)
165-
message_gle(-17, op, opts, s)
166-
end
167-
168146
defp handle_execute(:command, nil, [query], opts, s) do
169147
flags = Keyword.take(opts, @find_one_flags)
170148
op_query(coll: Utils.namespace("$cmd", s, opts[:database]), query: query, select: "", num_skip: 0, num_return: 1, flags: flags(flags))
@@ -184,22 +162,6 @@ defmodule Mongo.MongoDBConnection do
184162
end)
185163
end
186164

187-
defp message_gle(id, op, opts, s) do
188-
write_concern = Keyword.take(opts, @write_concern) |> Map.new
189-
write_concern = Map.merge(s.write_concern, write_concern)
190-
191-
if write_concern.w == 0 do
192-
with :ok <- Utils.send(id, op, s), do: {:ok, :ok, s}
193-
else
194-
command = BSON.Encoder.document([{:getLastError, 1}|Map.to_list(write_concern)])
195-
gle_op = op_query(coll: Utils.namespace("$cmd", s, opts[:database]), query: command,
196-
select: "", num_skip: 0, num_return: -1, flags: [])
197-
198-
ops = [{id, op}, {s.request_id, gle_op}]
199-
get_response(ops, s)
200-
end
201-
end
202-
203165
def ping(%{wire_version: wire_version} = state) do
204166
with {:ok, %{wire_version: ^wire_version}} <- wire_version(state), do: {:ok, state}
205167
end

lib/mongo/results.ex

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,11 @@ defmodule Mongo.UpdateResult do
5454
"""
5555

5656
@type t :: %__MODULE__{
57+
acknowledged: boolean,
5758
matched_count: non_neg_integer,
5859
modified_count: non_neg_integer,
5960
upserted_id: nil | BSON.ObjectId.t
6061
}
6162

62-
defstruct [:matched_count, :modified_count, :upserted_id]
63+
defstruct [acknowledged: true, matched_count: 0, modified_count: 0, upserted_id: 0]
6364
end

0 commit comments

Comments
 (0)