Skip to content

Commit 4a51f72

Browse files
committed
Merge pull request #400
2 parents 236e9bd + 6ec5348 commit 4a51f72

23 files changed

+418
-131
lines changed

php_phongo.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -962,7 +962,7 @@ void php_phongo_read_preference_to_zval(zval *retval, const mongoc_read_prefs_t
962962
const bson_t *tags = mongoc_read_prefs_get_tags(read_prefs);
963963
mongoc_read_mode_t mode = mongoc_read_prefs_get_mode(read_prefs);
964964

965-
array_init_size(retval, 2);
965+
array_init_size(retval, 3);
966966

967967
switch (mode) {
968968
case MONGOC_READ_PRIMARY: ADD_ASSOC_STRING(retval, "mode", "primary"); break;
@@ -987,6 +987,10 @@ void php_phongo_read_preference_to_zval(zval *retval, const mongoc_read_prefs_t
987987
ADD_ASSOC_ZVAL_EX(retval, "tags", state.zchild);
988988
#endif
989989
}
990+
991+
if (mongoc_read_prefs_get_max_staleness_ms(read_prefs) != 0) {
992+
ADD_ASSOC_LONG_EX(retval, "maxStalenessMS", mongoc_read_prefs_get_max_staleness_ms(read_prefs));
993+
}
990994
} /* }}} */
991995

992996
void php_phongo_write_concern_to_zval(zval *retval, const mongoc_write_concern_t *write_concern) /* {{{ */
@@ -1197,14 +1201,26 @@ static bool php_phongo_apply_rp_options_to_uri(mongoc_uri_t *uri, bson_t *option
11971201
/* Handle maxStalenessMS, and make sure it is not combined with primary
11981202
* readPreference */
11991203
if (bson_iter_init_find_case(&iter, options, "maxstalenessms") && BSON_ITER_HOLDS_INT32(&iter)) {
1204+
int32_t max_staleness_ms = bson_iter_int32(&iter);
1205+
1206+
if (max_staleness_ms < 0) {
1207+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected maxStalenessMS to be >= 0, %" PRId32 " given", max_staleness_ms);
1208+
mongoc_read_prefs_destroy(new_rp);
1209+
1210+
return false;
1211+
}
1212+
1213+
/* max_staleness_ms is fetched as an INT32, so there is no need to check
1214+
* if it exists INT32_MAX as we do in the ReadPreference constructor. */
1215+
12001216
if (mongoc_read_prefs_get_mode(new_rp) == MONGOC_READ_PRIMARY) {
12011217
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Primary read preference mode conflicts with maxStalenessMS");
12021218
mongoc_read_prefs_destroy(new_rp);
12031219

12041220
return false;
12051221
}
12061222

1207-
mongoc_read_prefs_set_max_staleness_ms(new_rp, bson_iter_int32(&iter));
1223+
mongoc_read_prefs_set_max_staleness_ms(new_rp, max_staleness_ms);
12081224
}
12091225

12101226
/* This may be redundant in light of the last check (primary with tags), but

src/MongoDB/ReadPreference.c

Lines changed: 60 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
#include <ext/standard/info.h>
3535
#include <Zend/zend_interfaces.h>
3636
#include <ext/spl/spl_iterators.h>
37+
/* PHP array helpers */
38+
#include "php_array_api.h"
3739
/* Our Compatability header */
3840
#include "phongo_compat.h"
3941

@@ -46,21 +48,22 @@ PHONGO_API zend_class_entry *php_phongo_readpreference_ce;
4648

4749
zend_object_handlers php_phongo_handler_readpreference;
4850

49-
/* {{{ proto void ReadPreference::__construct(integer $mode[, array $tagSets = array()])
51+
/* {{{ proto void ReadPreference::__construct(integer $mode[, array $tagSets = array()[, array $options = array()]])
5052
Constructs a new ReadPreference */
5153
PHP_METHOD(ReadPreference, __construct)
5254
{
5355
php_phongo_readpreference_t *intern;
5456
zend_error_handling error_handling;
5557
phongo_long mode;
5658
zval *tagSets = NULL;
59+
zval *options = NULL;
5760
SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value) SUPPRESS_UNUSED_WARNING(return_value_used)
5861

5962

6063
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
6164
intern = Z_READPREFERENCE_OBJ_P(getThis());
6265

63-
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|a!", &mode, &tagSets) == FAILURE) {
66+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|a!a!", &mode, &tagSets, &options) == FAILURE) {
6467
zend_restore_error_handling(&error_handling TSRMLS_CC);
6568
return;
6669
}
@@ -80,28 +83,46 @@ PHP_METHOD(ReadPreference, __construct)
8083
return;
8184
}
8285

83-
switch(ZEND_NUM_ARGS()) {
84-
case 2:
85-
if (tagSets) {
86-
bson_t *tags = bson_new();
86+
if (tagSets) {
87+
bson_t *tags = bson_new();
8788

88-
phongo_zval_to_bson(tagSets, PHONGO_BSON_NONE, (bson_t *)tags, NULL TSRMLS_CC);
89+
phongo_zval_to_bson(tagSets, PHONGO_BSON_NONE, (bson_t *)tags, NULL TSRMLS_CC);
8990

90-
if (!php_phongo_read_preference_tags_are_valid(tags)) {
91-
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "tagSets must be an array of zero or more documents");
92-
bson_destroy(tags);
93-
return;
94-
}
91+
if (!php_phongo_read_preference_tags_are_valid(tags)) {
92+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "tagSets must be an array of zero or more documents");
93+
bson_destroy(tags);
94+
return;
95+
}
96+
97+
if (!bson_empty(tags) && mode == MONGOC_READ_PRIMARY) {
98+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "tagSets may not be used with primary mode");
99+
bson_destroy(tags);
100+
return;
101+
}
102+
103+
mongoc_read_prefs_set_tags(intern->read_preference, tags);
104+
bson_destroy(tags);
105+
}
106+
107+
if (options && php_array_exists(options, "maxStalenessMS")) {
108+
phongo_long maxStalenessMS = php_array_fetchc_long(options, "maxStalenessMS");
95109

96-
if (!bson_empty(tags) && mode == MONGOC_READ_PRIMARY) {
97-
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "tagSets may not be used with primary mode");
98-
bson_destroy(tags);
99-
return;
100-
}
110+
if (maxStalenessMS < 0) {
111+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected maxStalenessMS to be >= 0, %" PHONGO_LONG_FORMAT " given", maxStalenessMS);
112+
return;
113+
}
114+
115+
if (maxStalenessMS > INT32_MAX) {
116+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected maxStalenessMS to be <= %" PRId32 ", %" PHONGO_LONG_FORMAT " given", INT32_MAX, maxStalenessMS);
117+
return;
118+
}
101119

102-
mongoc_read_prefs_set_tags(intern->read_preference, tags);
103-
bson_destroy(tags);
104-
}
120+
if (maxStalenessMS > 0 && mode == MONGOC_READ_PRIMARY) {
121+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "maxStalenessMS may not be used with primary mode");
122+
return;
123+
}
124+
125+
mongoc_read_prefs_set_max_staleness_ms(intern->read_preference, maxStalenessMS);
105126
}
106127

107128
if (!mongoc_read_prefs_is_valid(intern->read_preference)) {
@@ -111,6 +132,23 @@ PHP_METHOD(ReadPreference, __construct)
111132
}
112133
/* }}} */
113134

135+
/* {{{ proto integer ReadPreference::getMaxStalenessMS()
136+
Returns the ReadPreference maxStalenessMS value */
137+
PHP_METHOD(ReadPreference, getMaxStalenessMS)
138+
{
139+
php_phongo_readpreference_t *intern;
140+
SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used)
141+
142+
intern = Z_READPREFERENCE_OBJ_P(getThis());
143+
144+
if (zend_parse_parameters_none() == FAILURE) {
145+
return;
146+
}
147+
148+
RETURN_LONG(mongoc_read_prefs_get_max_staleness_ms(intern->read_preference));
149+
}
150+
/* }}} */
151+
114152
/* {{{ proto integer ReadPreference::getMode()
115153
Returns the ReadPreference mode */
116154
PHP_METHOD(ReadPreference, getMode)
@@ -184,13 +222,15 @@ PHP_METHOD(ReadPreference, bsonSerialize)
184222
ZEND_BEGIN_ARG_INFO_EX(ai_ReadPreference___construct, 0, 0, 1)
185223
ZEND_ARG_INFO(0, mode)
186224
ZEND_ARG_ARRAY_INFO(0, tagSets, 1)
225+
ZEND_ARG_ARRAY_INFO(0, options, 1)
187226
ZEND_END_ARG_INFO()
188227

189228
ZEND_BEGIN_ARG_INFO_EX(ai_ReadPreference_void, 0, 0, 0)
190229
ZEND_END_ARG_INFO()
191230

192231
static zend_function_entry php_phongo_readpreference_me[] = {
193232
PHP_ME(ReadPreference, __construct, ai_ReadPreference___construct, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
233+
PHP_ME(ReadPreference, getMaxStalenessMS, ai_ReadPreference_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
194234
PHP_ME(ReadPreference, getMode, ai_ReadPreference_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
195235
PHP_ME(ReadPreference, getTagSets, ai_ReadPreference_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
196236
PHP_ME(ReadPreference, bsonSerialize, ai_ReadPreference_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)

tests/manager/manager-ctor-001.phpt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
--TEST--
22
MongoDB\Driver\Manager::__construct() with default URI
3-
--SKIPIF--
4-
<?php require __DIR__ . "/../utils/basic-skipif.inc"; CLEANUP(STANDALONE) ?>
53
--FILE--
64
<?php
7-
require_once __DIR__ . "/../utils/basic.inc";
85

96
$manager = new MongoDB\Driver\Manager();
107

tests/manager/manager-ctor-003.phpt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
--TEST--
22
MongoDB\Driver\Manager::__construct() URI defaults to "mongodb://127.0.0.1/"
3-
--SKIPIF--
4-
<?php require __DIR__ . "/../utils/basic-skipif.inc"; CLEANUP(STANDALONE) ?>
53
--FILE--
64
<?php
7-
require_once __DIR__ . "/../utils/basic.inc";
85

96
ini_set('mongodb.debug', 'stderr');
107
$manager = new MongoDB\Driver\Manager();
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
--TEST--
2+
MongoDB\Driver\Manager::__construct(): read preference options
3+
--FILE--
4+
<?php
5+
6+
$tests = [
7+
['mongodb://127.0.0.1/?readPreference=primary', []],
8+
['mongodb://127.0.0.1/?readPreference=secondary&readPreferenceTags=tag:one&readPreferenceTags=', []],
9+
['mongodb://127.0.0.1/?readPreference=secondary&maxStalenessMS=1000', []],
10+
[null, ['readPreference' => 'primary']],
11+
[null, ['readPreference' => 'secondary', 'readPreferenceTags' => [['tag' => 'one'], []]]],
12+
[null, ['readPreference' => 'secondary', 'maxStalenessMS' => 1000]],
13+
];
14+
15+
foreach ($tests as $test) {
16+
list($uri, $options) = $test;
17+
18+
$manager = new MongoDB\Driver\Manager($uri, $options);
19+
var_dump($manager->getReadPreference());
20+
}
21+
22+
?>
23+
===DONE===
24+
<?php exit(0); ?>
25+
--EXPECTF--
26+
object(MongoDB\Driver\ReadPreference)#%d (%d) {
27+
["mode"]=>
28+
string(7) "primary"
29+
}
30+
object(MongoDB\Driver\ReadPreference)#%d (%d) {
31+
["mode"]=>
32+
string(9) "secondary"
33+
["tags"]=>
34+
array(2) {
35+
[0]=>
36+
array(1) {
37+
["tag"]=>
38+
string(3) "one"
39+
}
40+
[1]=>
41+
array(0) {
42+
}
43+
}
44+
}
45+
object(MongoDB\Driver\ReadPreference)#%d (%d) {
46+
["mode"]=>
47+
string(9) "secondary"
48+
["maxStalenessMS"]=>
49+
int(1000)
50+
}
51+
object(MongoDB\Driver\ReadPreference)#%d (%d) {
52+
["mode"]=>
53+
string(7) "primary"
54+
}
55+
object(MongoDB\Driver\ReadPreference)#%d (%d) {
56+
["mode"]=>
57+
string(9) "secondary"
58+
["tags"]=>
59+
array(2) {
60+
[0]=>
61+
array(1) {
62+
["tag"]=>
63+
string(3) "one"
64+
}
65+
[1]=>
66+
array(0) {
67+
}
68+
}
69+
}
70+
object(MongoDB\Driver\ReadPreference)#%d (%d) {
71+
["mode"]=>
72+
string(9) "secondary"
73+
["maxStalenessMS"]=>
74+
int(1000)
75+
}
76+
===DONE===
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
--TEST--
2+
MongoDB\Driver\Manager::__construct(): read preference options (maxStalenessMS)
3+
--FILE--
4+
<?php
5+
6+
$tests = [
7+
['mongodb://127.0.0.1/?readPreference=secondary&maxStalenessMS=1231', []],
8+
['mongodb://127.0.0.1/?readPreference=secondary', ['maxStalenessMS' => 1231]],
9+
['mongodb://127.0.0.1/?readPreference=secondary&maxStalenessMS=1000', ['maxStalenessMS' => 2000]],
10+
['mongodb://127.0.0.1/?readpreference=secondary&maxstalenessms=1231', []],
11+
['mongodb://127.0.0.1/?readpreference=secondary', ['maxstalenessms' => 1231]],
12+
];
13+
14+
foreach ($tests as $test) {
15+
list($uri, $options) = $test;
16+
17+
$manager = new MongoDB\Driver\Manager($uri, $options);
18+
var_dump($manager->getReadPreference());
19+
}
20+
21+
?>
22+
===DONE===
23+
--EXPECTF--
24+
object(MongoDB\Driver\ReadPreference)#%d (%d) {
25+
["mode"]=>
26+
string(9) "secondary"
27+
["maxStalenessMS"]=>
28+
int(1231)
29+
}
30+
object(MongoDB\Driver\ReadPreference)#%d (%d) {
31+
["mode"]=>
32+
string(9) "secondary"
33+
["maxStalenessMS"]=>
34+
int(1231)
35+
}
36+
object(MongoDB\Driver\ReadPreference)#%d (%d) {
37+
["mode"]=>
38+
string(9) "secondary"
39+
["maxStalenessMS"]=>
40+
int(2000)
41+
}
42+
object(MongoDB\Driver\ReadPreference)#%d (%d) {
43+
["mode"]=>
44+
string(9) "secondary"
45+
["maxStalenessMS"]=>
46+
int(1231)
47+
}
48+
object(MongoDB\Driver\ReadPreference)#%d (%d) {
49+
["mode"]=>
50+
string(9) "secondary"
51+
["maxStalenessMS"]=>
52+
int(1231)
53+
}
54+
===DONE===
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
--TEST--
2+
MongoDB\Driver\Manager::__construct(): read preference options of the wrong type are ignored
3+
--FILE--
4+
<?php
5+
6+
$tests = [
7+
['mongodb://127.0.0.1/?readPreference=secondary', ['readPreference' => 1]],
8+
['mongodb://127.0.0.1/?readPreference=secondary&readPreferenceTags=tag:one', ['readPreferenceTags' => 'invalid']],
9+
['mongodb://127.0.0.1/?readPreference=secondary&maxStalenessMS=1000', ['maxStalenessMS' => 'invalid']],
10+
];
11+
12+
foreach ($tests as $test) {
13+
list($uri, $options) = $test;
14+
15+
$manager = new MongoDB\Driver\Manager($uri, $options);
16+
var_dump($manager->getReadPreference());
17+
}
18+
19+
?>
20+
===DONE===
21+
--EXPECTF--
22+
object(MongoDB\Driver\ReadPreference)#%d (%d) {
23+
["mode"]=>
24+
string(9) "secondary"
25+
}
26+
object(MongoDB\Driver\ReadPreference)#%d (%d) {
27+
["mode"]=>
28+
string(9) "secondary"
29+
["tags"]=>
30+
array(1) {
31+
[0]=>
32+
array(1) {
33+
["tag"]=>
34+
string(3) "one"
35+
}
36+
}
37+
}
38+
object(MongoDB\Driver\ReadPreference)#%d (%d) {
39+
["mode"]=>
40+
string(9) "secondary"
41+
["maxStalenessMS"]=>
42+
int(1000)
43+
}
44+
===DONE===

0 commit comments

Comments
 (0)