@@ -695,7 +695,7 @@ defmodule Mongo do
695
695
# This is the implementation of the delete command for
696
696
# delete_one and delete_many
697
697
#
698
- defp delete_documents ( topology_pid , coll , filter , limit , opts \\ [ ] ) do
698
+ defp delete_documents ( topology_pid , coll , filter , limit , opts ) do
699
699
700
700
# see https://docs.mongodb.com/manual/reference/command/delete/#dbcmd.delete
701
701
write_concern = % {
@@ -749,20 +749,7 @@ defmodule Mongo do
749
749
@ spec replace_one ( GenServer . server , collection , BSON . document , BSON . document , Keyword . t ) :: result ( Mongo.UpdateResult . t )
750
750
def replace_one ( topology_pid , coll , filter , replacement , opts \\ [ ] ) do
751
751
_ = 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 )
766
753
end
767
754
768
755
@ doc """
@@ -795,20 +782,7 @@ defmodule Mongo do
795
782
@ spec update_one ( GenServer . server , collection , BSON . document , BSON . document , Keyword . t ) :: result ( Mongo.UpdateResult . t )
796
783
def update_one ( topology_pid , coll , filter , update , opts \\ [ ] ) do
797
784
_ = 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 )
812
786
end
813
787
814
788
@ doc """
@@ -834,18 +808,46 @@ defmodule Mongo do
834
808
@ spec update_many ( GenServer . server , collection , BSON . document , BSON . document , Keyword . t ) :: result ( Mongo.UpdateResult . t )
835
809
def update_many ( topology_pid , coll , filter , update , opts \\ [ ] ) do
836
810
_ = 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 ( )
837
840
838
- params = [ filter , update ]
839
- query = % Query { action: :update_many , extra: coll }
840
841
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
844
843
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
849
851
end
850
852
end
851
853
end
0 commit comments