Skip to content

Commit 12e6907

Browse files
committed
PHPC-448: Support readConcern option on Query
1 parent 92348ca commit 12e6907

File tree

6 files changed

+160
-0
lines changed

6 files changed

+160
-0
lines changed

php_phongo.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,10 @@ int phongo_execute_query(mongoc_client_t *client, const char *namespace, const p
597597
efree(dbname);
598598
efree(collname);
599599

600+
if (query->read_concern) {
601+
mongoc_collection_set_read_concern(collection, query->read_concern);
602+
}
603+
600604
cursor = mongoc_collection_find(collection, query->flags, query->skip, query->limit, query->batch_size, query->query, query->selector, read_preference);
601605
mongoc_collection_destroy(collection);
602606

php_phongo_classes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ typedef struct {
6767
uint32_t skip;
6868
uint32_t limit;
6969
uint32_t batch_size;
70+
mongoc_read_concern_t *read_concern;
7071
} php_phongo_query_t;
7172

7273
typedef struct {

src/MongoDB/Query.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@
3434
#include <ext/standard/info.h>
3535
#include <Zend/zend_interfaces.h>
3636
#include <ext/spl/spl_iterators.h>
37+
38+
/* PHP array helpers */
39+
#include "php_array_api.h"
40+
3741
/* Our Compatability header */
3842
#include "phongo_compat.h"
3943

@@ -75,8 +79,22 @@ PHP_METHOD(Query, __construct)
7579
zval_to_bson(zfilter, PHONGO_BSON_NONE, &bfilter, NULL TSRMLS_CC);
7680

7781
if (zoptions) {
82+
if (php_array_exists(zoptions, "readConcern")) {
83+
zval *zread_concern = php_array_fetchc(zoptions, "readConcern");
84+
85+
if (Z_TYPE_P(zread_concern) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(zread_concern), php_phongo_readconcern_ce TSRMLS_CC)) {
86+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"readConcern\" option to be %s, %s given", php_phongo_readconcern_ce->name, zend_get_type_by_const(Z_TYPE_P(zread_concern)));
87+
bson_clear(&intern->query);
88+
return;
89+
}
90+
91+
intern->read_concern = mongoc_read_concern_copy(phongo_read_concern_from_zval(zread_concern TSRMLS_CC));
92+
php_array_unsetc(zoptions, "readConcern");
93+
}
94+
7895
zval_to_bson(zoptions, PHONGO_BSON_NONE, &boptions, NULL TSRMLS_CC);
7996
}
97+
8098
if (!phongo_query_init(intern, &bfilter, &boptions TSRMLS_CC)) {
8199
bson_clear(&intern->query);
82100
}
@@ -117,6 +135,10 @@ static void php_phongo_query_free_object(void *object TSRMLS_DC) /* {{{ */
117135
bson_clear(&intern->query);
118136
}
119137

138+
if (intern->read_concern) {
139+
mongoc_read_concern_destroy(intern->read_concern);
140+
}
141+
120142
efree(intern);
121143
} /* }}} */
122144

tests/query/query-ctor_error-001.phpt

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
--TEST--
2+
MongoDB\Driver\ReadConcern construction (invalid readConcern type)
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
5+
--FILE--
6+
<?php
7+
require_once __DIR__ . "/../utils/basic.inc";
8+
9+
$tests = [
10+
1,
11+
1.0,
12+
'string',
13+
true,
14+
[],
15+
new stdClass,
16+
null,
17+
];
18+
19+
foreach ($tests as $test) {
20+
echo throws(function() use ($test) {
21+
new MongoDB\Driver\Query([], ['readConcern' => $test]);
22+
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
23+
}
24+
25+
?>
26+
===DONE===
27+
<?php exit(0); ?>
28+
--EXPECT--
29+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
30+
Expected "readConcern" option to be MongoDB\Driver\ReadConcern, integer given
31+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
32+
Expected "readConcern" option to be MongoDB\Driver\ReadConcern, double given
33+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
34+
Expected "readConcern" option to be MongoDB\Driver\ReadConcern, string given
35+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
36+
Expected "readConcern" option to be MongoDB\Driver\ReadConcern, boolean given
37+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
38+
Expected "readConcern" option to be MongoDB\Driver\ReadConcern, array given
39+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
40+
Expected "readConcern" option to be MongoDB\Driver\ReadConcern, object given
41+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
42+
Expected "readConcern" option to be MongoDB\Driver\ReadConcern, null given
43+
===DONE===

tests/replicaset/readconcern-001.phpt

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
--TEST--
2+
ReadConcern: MongoDB\Driver\Manager::executeQuery() with readConcern option (find command)
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"; CLEANUP(REPLICASET) ?>
5+
--FILE--
6+
<?php
7+
require_once __DIR__ . "/../utils/basic.inc";
8+
9+
$manager = new MongoDB\Driver\Manager(REPLICASET);
10+
11+
$wc = new MongoDB\Driver\WriteConcern(MongoDB\Driver\WriteConcern::MAJORITY);
12+
13+
$bulk = new MongoDB\Driver\BulkWrite();
14+
$bulk->insert(['_id' => 1, 'x' => 1]);
15+
$bulk->insert(['_id' => 2, 'x' => 2]);
16+
$manager->executeBulkWrite(NS, $bulk, $wc);
17+
18+
$rc = new MongoDB\Driver\ReadConcern(MongoDB\Driver\ReadConcern::LOCAL);
19+
$query = new MongoDB\Driver\Query(['x' => 2], ['readConcern' => $rc]);
20+
$cursor = $manager->executeQuery(NS, $query);
21+
22+
var_dump(iterator_to_array($cursor));
23+
24+
$rc = new MongoDB\Driver\ReadConcern(MongoDB\Driver\ReadConcern::MAJORITY);
25+
$query = new MongoDB\Driver\Query(['x' => 2], ['readConcern' => $rc]);
26+
$cursor = $manager->executeQuery(NS, $query);
27+
28+
var_dump(iterator_to_array($cursor));
29+
30+
?>
31+
===DONE===
32+
<?php exit(0); ?>
33+
--EXPECTF--
34+
array(1) {
35+
[0]=>
36+
object(stdClass)#%d (%d) {
37+
["_id"]=>
38+
int(2)
39+
["x"]=>
40+
int(2)
41+
}
42+
}
43+
array(1) {
44+
[0]=>
45+
object(stdClass)#%d (%d) {
46+
["_id"]=>
47+
int(2)
48+
["x"]=>
49+
int(2)
50+
}
51+
}
52+
===DONE===

tests/replicaset/readconcern-002.phpt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
--TEST--
2+
ReadConcern: MongoDB\Driver\Manager::executeQuery() with readConcern option (OP_QUERY)
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"; CLEANUP(REPLICASET_30) ?>
5+
--FILE--
6+
<?php
7+
require_once __DIR__ . "/../utils/basic.inc";
8+
9+
$manager = new MongoDB\Driver\Manager(REPLICASET_30);
10+
11+
$bulk = new MongoDB\Driver\BulkWrite();
12+
$bulk->insert(['_id' => 1, 'x' => 1]);
13+
$bulk->insert(['_id' => 2, 'x' => 2]);
14+
$manager->executeBulkWrite(NS, $bulk);
15+
16+
$rc = new MongoDB\Driver\ReadConcern(MongoDB\Driver\ReadConcern::LOCAL);
17+
$query = new MongoDB\Driver\Query(['x' => 2], ['readConcern' => $rc]);
18+
19+
echo throws(function() use ($manager, $query) {
20+
$manager->executeQuery(NS, $query);
21+
}, 'MongoDB\Driver\Exception\RuntimeException'), "\n";
22+
23+
$rc = new MongoDB\Driver\ReadConcern(MongoDB\Driver\ReadConcern::MAJORITY);
24+
$query = new MongoDB\Driver\Query(['x' => 2], ['readConcern' => $rc]);
25+
26+
echo throws(function() use ($manager, $query) {
27+
$manager->executeQuery(NS, $query);
28+
}, 'MongoDB\Driver\Exception\RuntimeException'), "\n";
29+
30+
?>
31+
===DONE===
32+
<?php exit(0); ?>
33+
--EXPECTF--
34+
OK: Got MongoDB\Driver\Exception\RuntimeException
35+
The selected server does not support readConcern
36+
OK: Got MongoDB\Driver\Exception\RuntimeException
37+
The selected server does not support readConcern
38+
===DONE===

0 commit comments

Comments
 (0)