Skip to content

Commit f12e200

Browse files
committed
PHPC-850: var_export() support for ReadPreference
1 parent 414cfa5 commit f12e200

File tree

6 files changed

+188
-56
lines changed

6 files changed

+188
-56
lines changed

phongo_compat.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,13 @@
136136
do { \
137137
(*x) = NULL; \
138138
} while (0)
139+
#define ZVAL_ARR(z, a) \
140+
do { \
141+
HashTable* __arr = (a); \
142+
zval* __z = (z); \
143+
Z_ARRVAL_P(__z) = __arr; \
144+
Z_TYPE_P(__z) = IS_ARRAY; \
145+
} while (0);
139146
#define phongo_free_object_arg void
140147
#define phongo_zpp_char_len int
141148
#define ZEND_HASH_APPLY_PROTECTION(ht) 1

php_phongo.c

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,52 +1266,6 @@ bool php_phongo_read_preference_tags_are_valid(const bson_t* tags) /* {{{ */
12661266
return true;
12671267
} /* }}} */
12681268

1269-
void php_phongo_read_preference_to_zval(zval* retval, const mongoc_read_prefs_t* read_prefs) /* {{{ */
1270-
{
1271-
const bson_t* tags = mongoc_read_prefs_get_tags(read_prefs);
1272-
mongoc_read_mode_t mode = mongoc_read_prefs_get_mode(read_prefs);
1273-
1274-
array_init_size(retval, 3);
1275-
1276-
switch (mode) {
1277-
case MONGOC_READ_PRIMARY:
1278-
ADD_ASSOC_STRING(retval, "mode", "primary");
1279-
break;
1280-
case MONGOC_READ_PRIMARY_PREFERRED:
1281-
ADD_ASSOC_STRING(retval, "mode", "primaryPreferred");
1282-
break;
1283-
case MONGOC_READ_SECONDARY:
1284-
ADD_ASSOC_STRING(retval, "mode", "secondary");
1285-
break;
1286-
case MONGOC_READ_SECONDARY_PREFERRED:
1287-
ADD_ASSOC_STRING(retval, "mode", "secondaryPreferred");
1288-
break;
1289-
case MONGOC_READ_NEAREST:
1290-
ADD_ASSOC_STRING(retval, "mode", "nearest");
1291-
break;
1292-
default: /* Do nothing */
1293-
break;
1294-
}
1295-
1296-
if (!bson_empty0(tags)) {
1297-
/* Use PHONGO_TYPEMAP_NATIVE_ARRAY for the root type since tags is an
1298-
* array; however, inner documents and arrays can use the default. */
1299-
php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER;
1300-
state.map.root_type = PHONGO_TYPEMAP_NATIVE_ARRAY;
1301-
1302-
php_phongo_bson_to_zval_ex(bson_get_data(tags), tags->len, &state);
1303-
#if PHP_VERSION_ID >= 70000
1304-
ADD_ASSOC_ZVAL_EX(retval, "tags", &state.zchild);
1305-
#else
1306-
ADD_ASSOC_ZVAL_EX(retval, "tags", state.zchild);
1307-
#endif
1308-
}
1309-
1310-
if (mongoc_read_prefs_get_max_staleness_seconds(read_prefs) != MONGOC_NO_MAX_STALENESS) {
1311-
ADD_ASSOC_LONG_EX(retval, "maxStalenessSeconds", mongoc_read_prefs_get_max_staleness_seconds(read_prefs));
1312-
}
1313-
} /* }}} */
1314-
13151269
void php_phongo_write_concern_to_zval(zval* retval, const mongoc_write_concern_t* write_concern) /* {{{ */
13161270
{
13171271
const char* wtag = mongoc_write_concern_get_wtag(write_concern);

php_phongo.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,6 @@ bool php_phongo_read_preference_tags_are_valid(const bson_t* tags);
155155

156156
void php_phongo_server_to_zval(zval* retval, mongoc_server_description_t* sd);
157157
void php_phongo_read_concern_to_zval(zval* retval, const mongoc_read_concern_t* read_concern);
158-
void php_phongo_read_preference_to_zval(zval* retval, const mongoc_read_prefs_t* read_prefs);
159158
void php_phongo_write_concern_to_zval(zval* retval, const mongoc_write_concern_t* write_concern);
160159
void php_phongo_cursor_to_zval(zval* retval, const mongoc_cursor_t* cursor);
161160

php_phongo_structs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ typedef struct {
9999
typedef struct {
100100
PHONGO_ZEND_OBJECT_PRE
101101
mongoc_read_prefs_t* read_preference;
102+
HashTable* properties;
102103
PHONGO_ZEND_OBJECT_POST
103104
} php_phongo_readpreference_t;
104105

src/MongoDB/ReadPreference.c

Lines changed: 102 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -202,17 +202,105 @@ static PHP_METHOD(ReadPreference, getTagSets)
202202
}
203203
} /* }}} */
204204

205+
static HashTable* php_phongo_readpreference_get_properties_hash(zval* object, bool is_debug TSRMLS_DC) /* {{{ */
206+
{
207+
php_phongo_readpreference_t* intern;
208+
HashTable* props;
209+
const char* modeString = NULL;
210+
const bson_t* tags;
211+
mongoc_read_mode_t mode;
212+
213+
intern = Z_READPREFERENCE_OBJ_P(object);
214+
215+
PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_debug, intern, props, 3);
216+
217+
if (!intern->read_preference) {
218+
return props;
219+
}
220+
221+
tags = mongoc_read_prefs_get_tags(intern->read_preference);
222+
mode = mongoc_read_prefs_get_mode(intern->read_preference);
223+
224+
switch (mode) {
225+
case MONGOC_READ_PRIMARY:
226+
modeString = "primary";
227+
break;
228+
case MONGOC_READ_PRIMARY_PREFERRED:
229+
modeString = "primaryPreferred";
230+
break;
231+
case MONGOC_READ_SECONDARY:
232+
modeString = "secondary";
233+
break;
234+
case MONGOC_READ_SECONDARY_PREFERRED:
235+
modeString = "secondaryPreferred";
236+
break;
237+
case MONGOC_READ_NEAREST:
238+
modeString = "nearest";
239+
break;
240+
default: /* Do nothing */
241+
break;
242+
}
243+
244+
if (modeString) {
245+
#if PHP_VERSION_ID >= 70000
246+
zval z_mode;
247+
248+
ZVAL_STRING(&z_mode, modeString);
249+
zend_hash_str_update(props, "mode", sizeof("mode") - 1, &z_mode);
250+
#else
251+
zval* z_mode;
252+
253+
MAKE_STD_ZVAL(z_mode);
254+
ZVAL_STRING(z_mode, modeString, 1);
255+
zend_hash_update(props, "mode", sizeof("mode"), &z_mode, sizeof(z_mode), NULL);
256+
#endif
257+
}
258+
259+
if (!bson_empty0(tags)) {
260+
/* Use PHONGO_TYPEMAP_NATIVE_ARRAY for the root type since tags is an
261+
* array; however, inner documents and arrays can use the default. */
262+
php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER;
263+
state.map.root_type = PHONGO_TYPEMAP_NATIVE_ARRAY;
264+
265+
php_phongo_bson_to_zval_ex(bson_get_data(tags), tags->len, &state);
266+
#if PHP_VERSION_ID >= 70000
267+
Z_ADDREF(state.zchild);
268+
zend_hash_str_update(props, "tags", sizeof("tags") - 1, &state.zchild);
269+
#else
270+
Z_ADDREF_P(state.zchild);
271+
zend_hash_update(props, "tags", sizeof("tags"), &state.zchild, sizeof(state.zchild), NULL);
272+
#endif
273+
zval_ptr_dtor(&state.zchild);
274+
}
275+
276+
if (mongoc_read_prefs_get_max_staleness_seconds(intern->read_preference) != MONGOC_NO_MAX_STALENESS) {
277+
long maxStalenessSeconds = mongoc_read_prefs_get_max_staleness_seconds(intern->read_preference);
278+
#if PHP_VERSION_ID >= 70000
279+
zval z_max_ss;
280+
281+
ZVAL_LONG(&z_max_ss, maxStalenessSeconds);
282+
zend_hash_str_update(props, "maxStalenessSeconds", sizeof("maxStalenessSeconds") - 1, &z_max_ss);
283+
#else
284+
zval* z_max_ss;
285+
286+
MAKE_STD_ZVAL(z_max_ss);
287+
ZVAL_LONG(z_max_ss, maxStalenessSeconds);
288+
zend_hash_update(props, "maxStalenessSeconds", sizeof("maxStalenessSeconds"), &z_max_ss, sizeof(z_max_ss), NULL);
289+
#endif
290+
}
291+
292+
return props;
293+
} /* }}} */
294+
205295
/* {{{ proto array MongoDB\Driver\ReadPreference::bsonSerialize()
206296
*/
207297
static PHP_METHOD(ReadPreference, bsonSerialize)
208298
{
209-
const mongoc_read_prefs_t* read_preference = phongo_read_preference_from_zval(getThis() TSRMLS_CC);
210-
211299
if (zend_parse_parameters_none() == FAILURE) {
212300
return;
213301
}
214302

215-
php_phongo_read_preference_to_zval(return_value, read_preference);
303+
ZVAL_ARR(return_value, php_phongo_readpreference_get_properties_hash(getThis(), true TSRMLS_CC));
216304
convert_to_object(return_value);
217305
} /* }}} */
218306

@@ -247,6 +335,11 @@ static void php_phongo_readpreference_free_object(phongo_free_object_arg* object
247335

248336
zend_object_std_dtor(&intern->std TSRMLS_CC);
249337

338+
if (intern->properties) {
339+
zend_hash_destroy(intern->properties);
340+
FREE_HASHTABLE(intern->properties);
341+
}
342+
250343
if (intern->read_preference) {
251344
mongoc_read_prefs_destroy(intern->read_preference);
252345
}
@@ -282,14 +375,13 @@ static phongo_create_object_retval php_phongo_readpreference_create_object(zend_
282375

283376
static HashTable* php_phongo_readpreference_get_debug_info(zval* object, int* is_temp TSRMLS_DC) /* {{{ */
284377
{
285-
zval retval = ZVAL_STATIC_INIT;
286-
const mongoc_read_prefs_t* read_prefs = phongo_read_preference_from_zval(object TSRMLS_CC);
287-
288378
*is_temp = 1;
379+
return php_phongo_readpreference_get_properties_hash(object, true TSRMLS_CC);
380+
} /* }}} */
289381

290-
php_phongo_read_preference_to_zval(&retval, read_prefs);
291-
292-
return Z_ARRVAL(retval);
382+
static HashTable* php_phongo_readpreference_get_properties(zval* object TSRMLS_DC) /* {{{ */
383+
{
384+
return php_phongo_readpreference_get_properties_hash(object, false TSRMLS_CC);
293385
} /* }}} */
294386
/* }}} */
295387

@@ -307,6 +399,7 @@ void php_phongo_readpreference_init_ce(INIT_FUNC_ARGS) /* {{{ */
307399

308400
memcpy(&php_phongo_handler_readpreference, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
309401
php_phongo_handler_readpreference.get_debug_info = php_phongo_readpreference_get_debug_info;
402+
php_phongo_handler_readpreference.get_properties = php_phongo_readpreference_get_properties;
310403
#if PHP_VERSION_ID >= 70000
311404
php_phongo_handler_readpreference.free_obj = php_phongo_readpreference_free_object;
312405
php_phongo_handler_readpreference.offset = XtOffsetOf(php_phongo_readpreference_t, std);
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
--TEST--
2+
MongoDB\Driver\ReadPreference: var_export()
3+
--FILE--
4+
<?php
5+
6+
require_once __DIR__ . '/../utils/tools.php';
7+
8+
$tests = [
9+
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY),
10+
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY_PREFERRED),
11+
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY),
12+
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY_PREFERRED),
13+
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_NEAREST),
14+
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY, []),
15+
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, [['dc' => 'ny']]),
16+
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, [['dc' => 'ny'], ['dc' => 'sf', 'use' => 'reporting'], []]),
17+
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, null, ['maxStalenessSeconds' => 1000]),
18+
];
19+
20+
foreach ($tests as $test) {
21+
echo var_export($test, true), "\n";
22+
}
23+
24+
?>
25+
===DONE===
26+
<?php exit(0); ?>
27+
--EXPECT--
28+
MongoDB\Driver\ReadPreference::__set_state(array(
29+
'mode' => 'primary',
30+
))
31+
MongoDB\Driver\ReadPreference::__set_state(array(
32+
'mode' => 'primaryPreferred',
33+
))
34+
MongoDB\Driver\ReadPreference::__set_state(array(
35+
'mode' => 'secondary',
36+
))
37+
MongoDB\Driver\ReadPreference::__set_state(array(
38+
'mode' => 'secondaryPreferred',
39+
))
40+
MongoDB\Driver\ReadPreference::__set_state(array(
41+
'mode' => 'nearest',
42+
))
43+
MongoDB\Driver\ReadPreference::__set_state(array(
44+
'mode' => 'primary',
45+
))
46+
MongoDB\Driver\ReadPreference::__set_state(array(
47+
'mode' => 'secondary',
48+
'tags' =>
49+
array (
50+
0 =>
51+
stdClass::__set_state(array(
52+
'dc' => 'ny',
53+
)),
54+
),
55+
))
56+
MongoDB\Driver\ReadPreference::__set_state(array(
57+
'mode' => 'secondary',
58+
'tags' =>
59+
array (
60+
0 =>
61+
stdClass::__set_state(array(
62+
'dc' => 'ny',
63+
)),
64+
1 =>
65+
stdClass::__set_state(array(
66+
'dc' => 'sf',
67+
'use' => 'reporting',
68+
)),
69+
2 =>
70+
stdClass::__set_state(array(
71+
)),
72+
),
73+
))
74+
MongoDB\Driver\ReadPreference::__set_state(array(
75+
'mode' => 'secondary',
76+
'maxStalenessSeconds' => 1000,
77+
))
78+
===DONE===

0 commit comments

Comments
 (0)