Skip to content

Commit 98727ae

Browse files
authored
PHPC-2005: Support 'let' option for multiple CRUD commands (#1312)
1 parent 4f576de commit 98727ae

13 files changed

+307
-14
lines changed

.evergreen/config.yml

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,14 +1126,15 @@ axes:
11261126
- id: libmongoc-version
11271127
display_name: libmongoc version
11281128
values:
1129-
- id: "lowest-supported"
1130-
display_name: "1.21.1"
1131-
variables:
1132-
LIBMONGOC_VERSION: "1.21.1"
1133-
- id: "upcoming-stable"
1134-
display_name: "1.21-dev"
1135-
variables:
1136-
LIBMONGOC_VERSION: "r1.21"
1129+
# TODO: enable lowest-supported and upcoming-stable after 1.22.0 is released and r1.22 is branched.
1130+
#- id: "lowest-supported"
1131+
# display_name: "1.22.0"
1132+
# variables:
1133+
# LIBMONGOC_VERSION: "1.22.0"
1134+
#- id: "upcoming-stable"
1135+
# display_name: "1.22-dev"
1136+
# variables:
1137+
# LIBMONGOC_VERSION: "r1.22"
11371138
- id: "latest-dev"
11381139
display_name: "1.22-dev (master)"
11391140
variables:

config.m4

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,14 +243,14 @@ if test "$PHP_MONGODB" != "no"; then
243243
AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
244244
AC_MSG_CHECKING(for libbson)
245245
if test -x "$PKG_CONFIG" && $PKG_CONFIG --exists libbson-1.0; then
246-
if $PKG_CONFIG libbson-1.0 --atleast-version 1.21.1; then
246+
if $PKG_CONFIG libbson-1.0 --atleast-version 1.22.0; then
247247
PHP_MONGODB_BSON_CFLAGS=`$PKG_CONFIG libbson-1.0 --cflags`
248248
PHP_MONGODB_BSON_LIBS=`$PKG_CONFIG libbson-1.0 --libs`
249249
PHP_MONGODB_BSON_VERSION=`$PKG_CONFIG libbson-1.0 --modversion`
250250
PHP_MONGODB_BSON_VERSION_STRING="System ($PHP_MONGODB_BSON_VERSION)"
251251
AC_MSG_RESULT(version $PHP_MONGODB_BSON_VERSION found)
252252
else
253-
AC_MSG_ERROR(system libbson must be upgraded to version >= 1.21.1)
253+
AC_MSG_ERROR(system libbson must be upgraded to version >= 1.22.0)
254254
fi
255255
else
256256
AC_MSG_ERROR(pkgconfig and libbson must be installed)
@@ -261,14 +261,14 @@ if test "$PHP_MONGODB" != "no"; then
261261

262262
AC_MSG_CHECKING(for libmongoc)
263263
if test -x "$PKG_CONFIG" && $PKG_CONFIG --exists libmongoc-1.0; then
264-
if $PKG_CONFIG libmongoc-1.0 --atleast-version 1.21.1; then
264+
if $PKG_CONFIG libmongoc-1.0 --atleast-version 1.22.0; then
265265
PHP_MONGODB_MONGOC_CFLAGS=`$PKG_CONFIG libmongoc-1.0 --cflags`
266266
PHP_MONGODB_MONGOC_LIBS=`$PKG_CONFIG libmongoc-1.0 --libs`
267267
PHP_MONGODB_MONGOC_VERSION=`$PKG_CONFIG libmongoc-1.0 --modversion`
268268
PHP_MONGODB_MONGOC_VERSION_STRING="System ($PHP_MONGODB_MONGOC_VERSION)"
269269
AC_MSG_RESULT(version $PHP_MONGODB_MONGOC_VERSION found)
270270
else
271-
AC_MSG_ERROR(system libmongoc must be upgraded to version >= 1.21.1)
271+
AC_MSG_ERROR(system libmongoc must be upgraded to version >= 1.22.0)
272272
fi
273273
else
274274
AC_MSG_ERROR(pkgconfig and libmongoc must be installed)

src/LIBMONGOC_VERSION_CURRENT

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.21.1
1+
1.11.1-20220328+git12b697c3da

src/MongoDB/BulkWrite.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ static PHP_METHOD(BulkWrite, __construct)
334334
intern->bulk = mongoc_bulk_operation_new(ordered);
335335
intern->ordered = ordered;
336336
intern->bypass = PHONGO_BULKWRITE_BYPASS_UNSET;
337+
intern->let = NULL;
337338
intern->num_ops = 0;
338339
intern->executed = false;
339340

@@ -342,6 +343,24 @@ static PHP_METHOD(BulkWrite, __construct)
342343
mongoc_bulk_operation_set_bypass_document_validation(intern->bulk, bypass);
343344
intern->bypass = bypass;
344345
}
346+
347+
if (options && php_array_existsc(options, "let")) {
348+
zval* value = php_array_fetch(options, "let");
349+
350+
if (Z_TYPE_P(value) != IS_OBJECT && Z_TYPE_P(value) != IS_ARRAY) {
351+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"let\" option to be array or object, %s given", zend_get_type_by_const(Z_TYPE_P(value)));
352+
return;
353+
}
354+
355+
intern->let = bson_new();
356+
php_phongo_zval_to_bson(value, PHONGO_BSON_NONE, intern->let, NULL);
357+
358+
if (EG(exception)) {
359+
return;
360+
}
361+
362+
mongoc_bulk_operation_set_let(intern->bulk, intern->let);
363+
}
345364
} /* }}} */
346365

347366
/* {{{ proto mixed MongoDB\Driver\BulkWrite::insert(array|object $document)
@@ -579,6 +598,10 @@ static void php_phongo_bulkwrite_free_object(zend_object* object) /* {{{ */
579598
mongoc_bulk_operation_destroy(intern->bulk);
580599
}
581600

601+
if (intern->let) {
602+
bson_clear(&intern->let);
603+
}
604+
582605
if (intern->database) {
583606
efree(intern->database);
584607
}
@@ -633,6 +656,17 @@ static HashTable* php_phongo_bulkwrite_get_debug_info(phongo_compat_object_handl
633656
ADD_ASSOC_NULL_EX(&retval, "bypassDocumentValidation");
634657
}
635658

659+
if (intern->let) {
660+
zval zv;
661+
662+
if (!php_phongo_bson_to_zval(bson_get_data(intern->let), intern->let->len, &zv)) {
663+
zval_ptr_dtor(&zv);
664+
goto done;
665+
}
666+
667+
ADD_ASSOC_ZVAL_EX(&retval, "let", &zv);
668+
}
669+
636670
ADD_ASSOC_BOOL_EX(&retval, "executed", intern->executed);
637671
ADD_ASSOC_LONG_EX(&retval, "server_id", mongoc_bulk_operation_get_hint(intern->bulk));
638672

@@ -652,6 +686,7 @@ static HashTable* php_phongo_bulkwrite_get_debug_info(phongo_compat_object_handl
652686
ADD_ASSOC_NULL_EX(&retval, "write_concern");
653687
}
654688

689+
done:
655690
return Z_ARRVAL(retval);
656691
} /* }}} */
657692
/* }}} */

src/MongoDB/Query.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,7 @@ static bool php_phongo_query_init(php_phongo_query_t* intern, zval* filter, zval
299299
PHONGO_QUERY_OPT_STRING("comment", options, "comment")
300300
else PHONGO_QUERY_OPT_STRING("comment", modifiers, "$comment");
301301
PHONGO_QUERY_OPT_BOOL("exhaust", options, "exhaust");
302+
PHONGO_QUERY_OPT_DOCUMENT("let", options, "let");
302303
PHONGO_QUERY_OPT_DOCUMENT("max", options, "max")
303304
else PHONGO_QUERY_OPT_DOCUMENT("max", modifiers, "$max");
304305
PHONGO_QUERY_OPT_INT64_DEPRECATED("maxScan", options, "maxScan")

src/libmongoc

Submodule libmongoc updated 119 files

src/phongo_structs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ typedef struct {
2929
size_t num_ops;
3030
bool ordered;
3131
int bypass;
32+
bson_t* let;
3233
char* database;
3334
char* collection;
3435
bool executed;
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
--TEST--
2+
MongoDB\Driver\BulkWrite::__construct(): let option
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
5+
<?php skip_if_not_live(); ?>
6+
<?php skip_if_server_version('<', '5.0'); ?>
7+
<?php skip_if_not_clean(); ?>
8+
--FILE--
9+
<?php
10+
11+
require_once __DIR__ . "/../utils/basic.inc";
12+
13+
class CommandLogger implements MongoDB\Driver\Monitoring\CommandSubscriber
14+
{
15+
public function commandStarted(MongoDB\Driver\Monitoring\CommandStartedEvent $event)
16+
{
17+
$command = $event->getCommand();
18+
19+
if (!isset($command->let)) {
20+
printf("%s does not include let option\n", $event->getCommandName());
21+
22+
return;
23+
}
24+
25+
printf("%s included let: %s\n", $event->getCommandName(), json_encode($event->getCommand()->let));
26+
}
27+
28+
public function commandSucceeded(MongoDB\Driver\Monitoring\CommandSucceededEvent $event)
29+
{
30+
}
31+
32+
public function commandFailed(MongoDB\Driver\Monitoring\CommandFailedEvent $event)
33+
{
34+
}
35+
}
36+
37+
$manager = create_test_manager();
38+
39+
$bulk = new MongoDB\Driver\BulkWrite(['let' => ['id' => 1, 'x' => 'foo']]);
40+
$bulk->insert(['_id' => 1]);
41+
$bulk->insert(['_id' => 2]);
42+
$bulk->delete(['$expr' => ['$eq' => ['$_id', '$$id']]]);
43+
$bulk->update(['_id' => 2], [['$set' => ['x' => '$$x']]]);
44+
45+
$manager->addSubscriber(new CommandLogger);
46+
$manager->executeBulkWrite(NS, $bulk);
47+
48+
$cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([]));
49+
var_dump($cursor->toArray());
50+
51+
?>
52+
===DONE===
53+
<?php exit(0); ?>
54+
--EXPECTF--
55+
insert does not include let option
56+
delete included let: {"id":1,"x":"foo"}
57+
update included let: {"id":1,"x":"foo"}
58+
find does not include let option
59+
array(1) {
60+
[0]=>
61+
object(stdClass)#%d (%d) {
62+
["_id"]=>
63+
int(2)
64+
["x"]=>
65+
string(3) "foo"
66+
}
67+
}
68+
===DONE===
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--TEST--
2+
MongoDB\Driver\BulkWrite::__construct(): let option
3+
--FILE--
4+
<?php
5+
6+
require_once __DIR__ . '/../utils/basic.inc';
7+
8+
$invalidValues = [true, 1, 'string', null];
9+
10+
foreach ($invalidValues as $invalidValue) {
11+
echo throws(function() use ($invalidValue) {
12+
new MongoDB\Driver\BulkWrite(['let' => $invalidValue]);
13+
}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n";
14+
}
15+
16+
?>
17+
===DONE===
18+
<?php exit(0); ?>
19+
--EXPECTF--
20+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
21+
Expected "let" option to be array or object, %r(bool|boolean)%r given
22+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
23+
Expected "let" option to be array or object, %r(int|integer)%r given
24+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
25+
Expected "let" option to be array or object, string given
26+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
27+
Expected "let" option to be array or object, null given
28+
===DONE===

tests/bulk/bulkwrite-debug-001.phpt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ $tests = [
99
['ordered' => false],
1010
['bypassDocumentValidation' => true],
1111
['bypassDocumentValidation' => false],
12+
['let' => ['id' => 1, 'x' => 'foo']],
1213
];
1314

1415
foreach ($tests as $options) {
@@ -109,4 +110,29 @@ object(MongoDB\Driver\BulkWrite)#%d (%d) {
109110
["write_concern"]=>
110111
NULL
111112
}
113+
object(MongoDB\Driver\BulkWrite)#%d (%d) {
114+
["database"]=>
115+
NULL
116+
["collection"]=>
117+
NULL
118+
["ordered"]=>
119+
bool(true)
120+
["bypassDocumentValidation"]=>
121+
NULL
122+
["let"]=>
123+
object(stdClass)#%d (%d) {
124+
["id"]=>
125+
int(1)
126+
["x"]=>
127+
string(3) "foo"
128+
}
129+
["executed"]=>
130+
bool(false)
131+
["server_id"]=>
132+
int(0)
133+
["session"]=>
134+
NULL
135+
["write_concern"]=>
136+
NULL
137+
}
112138
===DONE===

0 commit comments

Comments
 (0)