Skip to content

Commit 85447eb

Browse files
authored
PHPLIB-1492: Support sort option for updateOne and replaceOne (#1605)
Addresses both single-statement updates and bulk writes. * Require PHPC 1.21-dev for CI builds
1 parent d1aea99 commit 85447eb

File tree

15 files changed

+140
-25
lines changed

15 files changed

+140
-25
lines changed

.evergreen/config/generated/build/build-extension.yml

Lines changed: 36 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.evergreen/config/templates/build/build-extension.yml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
vars:
66
PHP_VERSION: "%phpVersion%"
77
- func: "compile extension"
8+
# TODO: remove once 1.21.0 is released
9+
vars:
10+
EXTENSION_BRANCH: "v1.x"
811
- func: "upload extension"
912
- name: "build-php-%phpVersion%-lowest"
1013
tags: ["build", "php%phpVersion%", "lowest", "pr", "tag"]
@@ -14,7 +17,9 @@
1417
PHP_VERSION: "%phpVersion%"
1518
- func: "compile extension"
1619
vars:
17-
EXTENSION_VERSION: "1.20.0"
20+
# TODO: change to "EXTENSION_VERSION: 1.21.0" once 1.21.0 is released
21+
# EXTENSION_VERSION: "1.21.0"
22+
EXTENSION_BRANCH: "v1.x"
1823
- func: "upload extension"
1924
- name: "build-php-%phpVersion%-next-stable"
2025
tags: ["build", "php%phpVersion%", "next-stable", "pr", "tag"]
@@ -24,7 +29,9 @@
2429
PHP_VERSION: "%phpVersion%"
2530
- func: "compile extension"
2631
vars:
27-
EXTENSION_BRANCH: "v1.20"
32+
# TODO: change to "v1.21" once 1.21.0 is released
33+
# EXTENSION_BRANCH: "v1.21"
34+
EXTENSION_BRANCH: "v1.x"
2835
- func: "upload extension"
2936
- name: "build-php-%phpVersion%-next-minor"
3037
tags: ["build", "php%phpVersion%", "next-minor"]

.github/workflows/coding-standards.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ on:
1313

1414
env:
1515
PHP_VERSION: "8.2"
16-
DRIVER_VERSION: "stable"
16+
# TODO: change to "stable" once 1.21.0 is released
17+
# DRIVER_VERSION: "stable"
18+
DRIVER_VERSION: "mongodb/[email protected]"
1719

1820
jobs:
1921
phpcs:

.github/workflows/generator.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ on:
1313

1414
env:
1515
PHP_VERSION: "8.2"
16-
# TODO: change to "stable" once 1.20.0 is released
16+
# TODO: change to "stable" once 1.21.0 is released
1717
# DRIVER_VERSION: "stable"
18-
DRIVER_VERSION: "mongodb/mongo-php-driver@v1.20"
18+
DRIVER_VERSION: "mongodb/mongo-php-driver@v1.x"
1919

2020
jobs:
2121
psalm:

.github/workflows/static-analysis.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ on:
1919

2020
env:
2121
PHP_VERSION: "8.2"
22-
DRIVER_VERSION: "stable"
22+
# TODO: change to "stable" once 1.21.0 is released
23+
# DRIVER_VERSION: "stable"
24+
DRIVER_VERSION: "mongodb/[email protected]"
2325

2426
jobs:
2527
psalm:

.github/workflows/tests.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ on:
1212
- "feature/*"
1313

1414
env:
15-
DRIVER_VERSION: "stable"
15+
# TODO: change to "stable" once 1.21.0 is released
16+
# DRIVER_VERSION: "stable"
17+
DRIVER_VERSION: "mongodb/[email protected]"
1618

1719
jobs:
1820
phpunit:

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"php": "^8.1",
1414
"ext-hash": "*",
1515
"ext-json": "*",
16-
"ext-mongodb": "^1.20.0",
16+
"ext-mongodb": "^1.21.0",
1717
"composer-runtime-api": "^2.0",
1818
"psr/log": "^1.1.4|^2|^3",
1919
"symfony/polyfill-php80": "^1.27",

src/Operation/BulkWrite.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,14 @@ class BulkWrite implements Executable
9191
* * upsert (boolean): When true, a new document is created if no document
9292
* matches the query. The default is false.
9393
*
94+
* Supported options for replaceOne and updateOne operations:
95+
*
96+
* * sort (document): Determines which document the operation modifies if
97+
* the query selects multiple documents.
98+
*
99+
* This is not supported for server versions < 8.0 and will result in an
100+
* exception at execution time if used.
101+
*
94102
* Supported options for updateMany and updateOne operations:
95103
*
96104
* * arrayFilters (document array): A set of filters specifying to which
@@ -372,6 +380,10 @@ private function validateOperations(array $operations, ?DocumentCodec $codec, En
372380
throw InvalidArgumentException::expectedDocumentType(sprintf('$operations[%d]["%s"][2]["collation"]', $i, $type), $args[2]['collation']);
373381
}
374382

383+
if (isset($args[2]['sort']) && ! is_document($args[2]['sort'])) {
384+
throw InvalidArgumentException::expectedDocumentType(sprintf('$operations[%d]["%s"][2]["sort"]', $i, $type), $args[2]['sort']);
385+
}
386+
375387
if (! is_bool($args[2]['upsert'])) {
376388
throw InvalidArgumentException::invalidType(sprintf('$operations[%d]["%s"][2]["upsert"]', $i, $type), $args[2]['upsert'], 'boolean');
377389
}
@@ -413,6 +425,14 @@ private function validateOperations(array $operations, ?DocumentCodec $codec, En
413425
throw InvalidArgumentException::expectedDocumentType(sprintf('$operations[%d]["%s"][2]["collation"]', $i, $type), $args[2]['collation']);
414426
}
415427

428+
if (isset($args[2]['sort']) && ! is_document($args[2]['sort'])) {
429+
throw InvalidArgumentException::expectedDocumentType(sprintf('$operations[%d]["%s"][2]["sort"]', $i, $type), $args[2]['sort']);
430+
}
431+
432+
if (isset($args[2]['sort']) && $args[2]['multi']) {
433+
throw new InvalidArgumentException(sprintf('"sort" option cannot be used with $operations[%d]["%s"]', $i, $type));
434+
}
435+
416436
if (! is_bool($args[2]['upsert'])) {
417437
throw InvalidArgumentException::invalidType(sprintf('$operations[%d]["%s"][2]["upsert"]', $i, $type), $args[2]['upsert'], 'boolean');
418438
}

src/Operation/ReplaceOne.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ class ReplaceOne implements Executable
7474
* Parameters can then be accessed as variables in an aggregate
7575
* expression context (e.g. "$$var").
7676
*
77+
* * sort (document): Determines which document the operation modifies if
78+
* the query selects multiple documents.
79+
*
80+
* This is not supported for server versions < 8.0 and will result in an
81+
* exception at execution time if used.
82+
*
7783
* * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
7884
*
7985
* @param string $databaseName Database name

src/Operation/Update.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,14 @@ public function __construct(private string $databaseName, private string $collec
149149
throw InvalidArgumentException::expectedDocumentType('"let" option', $options['let']);
150150
}
151151

152+
if (isset($options['sort']) && ! is_document($options['sort'])) {
153+
throw InvalidArgumentException::expectedDocumentType('"sort" option', $options['sort']);
154+
}
155+
156+
if (isset($options['sort']) && $options['multi']) {
157+
throw new InvalidArgumentException('"sort" option cannot be used with multi-document updates');
158+
}
159+
152160
if (isset($options['bypassDocumentValidation']) && ! $options['bypassDocumentValidation']) {
153161
unset($options['bypassDocumentValidation']);
154162
}
@@ -270,8 +278,10 @@ private function createUpdateOptions(): array
270278
}
271279
}
272280

273-
if (isset($this->options['collation'])) {
274-
$updateOptions['collation'] = (object) $this->options['collation'];
281+
foreach (['collation', 'sort'] as $option) {
282+
if (isset($this->options[$option])) {
283+
$updateOptions[$option] = (object) $this->options[$option];
284+
}
275285
}
276286

277287
return $updateOptions;

0 commit comments

Comments
 (0)