7
7
use MongoDB \Client ;
8
8
use MongoDB \Collection ;
9
9
use MongoDB \Database ;
10
+ use MongoDB \Driver \BulkWriteCommand ;
10
11
use MongoDB \Driver \ClientEncryption ;
11
12
use MongoDB \Driver \Cursor ;
12
13
use MongoDB \Driver \Server ;
@@ -88,7 +89,6 @@ final class Operation
88
89
'createEntities ' => 'createEntities is not implemented (PHPC-1760) ' ,
89
90
],
90
91
Client::class => [
91
- 'clientBulkWrite ' => 'clientBulkWrite is not implemented (PHPLIB-847) ' ,
92
92
'listDatabaseObjects ' => 'listDatabaseObjects is not implemented ' ,
93
93
],
94
94
Cursor::class => ['iterateOnce ' => 'iterateOnce is not implemented (PHPC-1760) ' ],
@@ -257,6 +257,18 @@ private function executeForClient(Client $client)
257
257
Util::assertArgumentsBySchema (Client::class, $ this ->name , $ args );
258
258
259
259
switch ($ this ->name ) {
260
+ case 'clientBulkWrite ' :
261
+ assertArrayHasKey ('models ' , $ args );
262
+ assertIsArray ($ args ['models ' ]);
263
+
264
+ // Options for BulkWriteCommand and Server::executeBulkWriteCommand() will be mixed
265
+ $ options = array_diff_key ($ args , ['models ' => 1 ]);
266
+
267
+ return $ client ->bulkWrite (
268
+ self ::prepareBulkWriteCommand ($ args ['models ' ], $ options ),
269
+ $ options ,
270
+ );
271
+
260
272
case 'createChangeStream ' :
261
273
assertArrayHasKey ('pipeline ' , $ args );
262
274
assertIsArray ($ args ['pipeline ' ]);
@@ -1001,6 +1013,82 @@ private function skipIfOperationIsNotSupported(string $executingObjectName): voi
1001
1013
Assert::markTestSkipped ($ skipReason );
1002
1014
}
1003
1015
1016
+ private static function prepareBulkWriteCommand (array $ models , array $ options ): BulkWriteCommand
1017
+ {
1018
+ $ bulk = new BulkWriteCommand ($ options );
1019
+
1020
+ foreach ($ models as $ model ) {
1021
+ $ model = (array ) $ model ;
1022
+ assertCount (1 , $ model );
1023
+
1024
+ $ type = key ($ model );
1025
+ $ args = current ($ model );
1026
+ assertIsObject ($ args );
1027
+ $ args = (array ) $ args ;
1028
+
1029
+ assertArrayHasKey ('namespace ' , $ args );
1030
+ assertIsString ($ args ['namespace ' ]);
1031
+
1032
+ switch ($ type ) {
1033
+ case 'deleteMany ' :
1034
+ case 'deleteOne ' :
1035
+ assertArrayHasKey ('filter ' , $ args );
1036
+ assertInstanceOf (stdClass::class, $ args ['filter ' ]);
1037
+
1038
+ $ bulk ->{$ type }(
1039
+ $ args ['namespace ' ],
1040
+ $ args ['filter ' ],
1041
+ array_diff_key ($ args , ['namespace ' => 1 , 'filter ' => 1 ]),
1042
+ );
1043
+ break ;
1044
+
1045
+ case 'insertOne ' :
1046
+ assertArrayHasKey ('document ' , $ args );
1047
+ assertInstanceOf (stdClass::class, $ args ['document ' ]);
1048
+
1049
+ $ bulk ->insertOne (
1050
+ $ args ['namespace ' ],
1051
+ $ args ['document ' ],
1052
+ );
1053
+ break ;
1054
+
1055
+ case 'replaceOne ' :
1056
+ assertArrayHasKey ('filter ' , $ args );
1057
+ assertArrayHasKey ('replacement ' , $ args );
1058
+ assertInstanceOf (stdClass::class, $ args ['filter ' ]);
1059
+ assertInstanceOf (stdClass::class, $ args ['replacement ' ]);
1060
+
1061
+ $ bulk ->replaceOne (
1062
+ $ args ['namespace ' ],
1063
+ $ args ['filter ' ],
1064
+ $ args ['replacement ' ],
1065
+ array_diff_key ($ args , ['namespace ' => 1 , 'filter ' => 1 , 'replacement ' => 1 ]),
1066
+ );
1067
+ break ;
1068
+
1069
+ case 'updateMany ' :
1070
+ case 'updateOne ' :
1071
+ assertArrayHasKey ('filter ' , $ args );
1072
+ assertArrayHasKey ('update ' , $ args );
1073
+ assertInstanceOf (stdClass::class, $ args ['filter ' ]);
1074
+ assertThat ($ args ['update ' ], logicalOr (new IsType ('array ' ), new IsType ('object ' )));
1075
+
1076
+ $ bulk ->{$ type }(
1077
+ $ args ['namespace ' ],
1078
+ $ args ['filter ' ],
1079
+ $ args ['update ' ],
1080
+ array_diff_key ($ args , ['namespace ' => 1 , 'filter ' => 1 , 'update ' => 1 ]),
1081
+ );
1082
+ break ;
1083
+
1084
+ default :
1085
+ Assert::fail ('Unsupported bulk write model: ' . $ type );
1086
+ }
1087
+ }
1088
+
1089
+ return $ bulk ;
1090
+ }
1091
+
1004
1092
private static function prepareBulkWriteRequest (stdClass $ request ): array
1005
1093
{
1006
1094
$ request = (array ) $ request ;
@@ -1026,6 +1114,7 @@ private static function prepareBulkWriteRequest(stdClass $request): array
1026
1114
1027
1115
case 'insertOne ' :
1028
1116
assertArrayHasKey ('document ' , $ args );
1117
+ assertInstanceOf (stdClass::class, $ args ['document ' ]);
1029
1118
1030
1119
return ['insertOne ' => [$ args ['document ' ]]];
1031
1120
0 commit comments