Skip to content

Commit 265643d

Browse files
committed
PHP-1312: Implement Collection::bulkWrite()
1 parent b9953f4 commit 265643d

File tree

2 files changed

+133
-7
lines changed

2 files changed

+133
-7
lines changed

examples/write.php

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,60 @@
155155
} catch(Exception $e) {
156156
printf("Caught exception '%s', on line %d\n", $e->getMessage(), __LINE__);
157157
exit;
158-
159158
}
160159

160+
161+
try {
162+
$result = $collection->bulkWrite(
163+
// Required writes param (an array of operations)
164+
[
165+
// Like explain(), operations identified by single key
166+
[
167+
'insertOne' => [
168+
['x' => 1]
169+
],
170+
],
171+
[
172+
'updateMany' => [
173+
['x' => 1],
174+
['$set' => ['x' => 2]],
175+
],
176+
],
177+
[
178+
'updateOne' => [
179+
['x' => 3],
180+
['$set' => ['x' => 4]],
181+
// Optional params are still permitted
182+
['upsert' => true],
183+
],
184+
],
185+
[
186+
'deleteOne' => [
187+
['x' => 1],
188+
],
189+
],
190+
[
191+
'deleteMany' => [
192+
// Required arguments must still be specified
193+
[],
194+
],
195+
],
196+
],
197+
// Optional named params in an associative array
198+
['ordered' => false]
199+
);
200+
printf("insertedCount: %d\n", $result->getInsertedCount());
201+
printf("matchedCount: %d\n", $result->getMatchedCount());
202+
printf("modifiedCount: %d\n", $result->getModifiedCount());
203+
printf("upsertedCount: %d\n", $result->getUpsertedCount());
204+
printf("deletedCount: %d\n", $result->getDeletedCount());
205+
206+
foreach ($result->getUpsertedIds() as $index => $id) {
207+
printf("upsertedId[%d]: %s", $index, $id);
208+
}
209+
210+
} catch(Exception $e) {
211+
printf("Caught exception '%s', on line %d\n", $e->getMessage(), __LINE__);
212+
echo $e->getTraceAsString(), "\n";
213+
exit;
214+
}

src/MongoDB/Collection.php

Lines changed: 78 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,78 @@ function getWriteOptions() { /* {{{ */
179179
"limit" => 1,
180180
);
181181
} /* }}} */
182+
function getBulkOptions() { /* {{{ */
183+
return array(
184+
"ordered" => false,
185+
);
186+
} /* }}} */
187+
188+
function bulkWrite(array $bulk, array $options = array()) {
189+
$options = array_merge($this->getBulkOptions(), $options);
190+
191+
$batch = new WriteBatch($options["ordered"]);
192+
193+
foreach($bulk as $n => $op) {
194+
foreach($op as $opname => $args) {
195+
if (!isset($args[0])) {
196+
throw \RuntimeException(sprintf("Missing argument#1 for '%s' (operation#%d)", $opname, $n));
197+
}
198+
199+
switch($opname) {
200+
case "insertOne":
201+
$batch->insert($args[0]);
202+
break;
203+
204+
case "updateMany":
205+
if (!isset($args[1])) {
206+
throw \RuntimeException(sprintf("Missing argument#2 for '%s' (operation#%d)", $opname, $n));
207+
}
208+
$options = array_merge($this->getWriteOptions(), isset($args[2]) ? $args[2] : array(), array("limit" => 0));
209+
210+
$batch->update($args[0], $args[1], $options);
211+
break;
212+
213+
case "updateOne":
214+
if (!isset($args[1])) {
215+
throw \RuntimeException(sprintf("Missing argument#2 for '%s' (operation#%d)", $opname, $n));
216+
}
217+
$options = array_merge($this->getWriteOptions(), isset($args[2]) ? $args[2] : array(), array("limit" => 1));
218+
if (key($args[1])[0] != '$') {
219+
throw new \RuntimeException("First key in \$update must be a \$operator");
220+
}
221+
222+
$batch->update($args[0], $args[1], $options);
223+
break;
224+
225+
case "replaceOne":
226+
if (!isset($args[1])) {
227+
throw \RuntimeException(sprintf("Missing argument#2 for '%s' (operation#%d)", $opname, $n));
228+
}
229+
$options = array_merge($this->getWriteOptions(), isset($args[2]) ? $args[2] : array(), array("limit" => 1));
230+
if (key($args[1])[0] == '$') {
231+
throw new \RuntimeException("First key in \$update must NOT be a \$operator");
232+
}
233+
234+
$batch->update($args[0], $args[1], $options);
235+
break;
236+
237+
case "deleteOne":
238+
$options = array_merge($this->getWriteOptions(), isset($args[1]) ? $args[1] : array(), array("limit" => 1));
239+
$batch->delete($args[0], $options);
240+
break;
241+
242+
case "deleteMany":
243+
$options = array_merge($this->getWriteOptions(), isset($args[1]) ? $args[1] : array(), array("limit" => 1));
244+
$batch->delete($args[0], $options);
245+
break;
246+
247+
default:
248+
throw \RuntimeException(sprintf("Unknown operation type called '%s' (operation#%d)", $opname, $n));
249+
}
250+
}
251+
}
252+
return $this->manager->executeWriteBatch($this->ns, $batch, $this->wc);
253+
}
182254

183255
function insertOne(array $filter) { /* {{{ */
184256
$options = array_merge($this->getWriteOptions());
@@ -215,17 +287,17 @@ protected function _update($filter, $update, $options) { /* {{{ */
215287
$batch->update($filter, $update, $options);
216288
return $this->manager->executeWriteBatch($this->ns, $batch, $this->wc);
217289
} /* }}} */
218-
function updateOne(array $filter, array $update, array $options = array()) { /* {{{ */
219-
if (key($update)[0] != '$') {
220-
throw new \RuntimeException("First key in \$update must be a \$operator");
290+
function replaceOne(array $filter, array $update, array $options = array()) { /* {{{ */
291+
if (key($update)[0] == '$') {
292+
throw new \RuntimeException("First key in \$update must NOT be a \$operator");
221293
}
222294
$wr = $this->_update($filter, $update, $options);
223295

224296
return new UpdateResult($wr);
225297
} /* }}} */
226-
function replaceOne(array $filter, array $update, array $options = array()) { /* {{{ */
227-
if (key($update)[0] == '$') {
228-
throw new \RuntimeException("First key in \$update must NOT be a \$operator");
298+
function updateOne(array $filter, array $update, array $options = array()) { /* {{{ */
299+
if (key($update)[0] != '$') {
300+
throw new \RuntimeException("First key in \$update must be a \$operator");
229301
}
230302
$wr = $this->_update($filter, $update, $options);
231303

0 commit comments

Comments
 (0)