Skip to content

Commit 43c95d2

Browse files
committed
Add properties to ReadPreference class
1 parent 47bb9a3 commit 43c95d2

23 files changed

+700
-135
lines changed

src/MongoDB/ReadPreference.c

Lines changed: 98 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,71 @@
3131

3232
zend_class_entry* phongo_readpreference_ce;
3333

34+
static const char* phongo_readpreference_get_mode_string(const mongoc_read_prefs_t* read_prefs)
35+
{
36+
switch (mongoc_read_prefs_get_mode(read_prefs)) {
37+
case MONGOC_READ_PRIMARY:
38+
return PHONGO_READ_PRIMARY;
39+
case MONGOC_READ_PRIMARY_PREFERRED:
40+
return PHONGO_READ_PRIMARY_PREFERRED;
41+
case MONGOC_READ_SECONDARY:
42+
return PHONGO_READ_SECONDARY;
43+
case MONGOC_READ_SECONDARY_PREFERRED:
44+
return PHONGO_READ_SECONDARY_PREFERRED;
45+
case MONGOC_READ_NEAREST:
46+
return PHONGO_READ_NEAREST;
47+
default:
48+
return "";
49+
}
50+
}
51+
52+
static void phongo_readpreference_update_properties(phongo_readpreference_t* intern)
53+
{
54+
const bson_t* bson;
55+
56+
zend_update_property_string(phongo_readpreference_ce, &intern->std, ZEND_STRL("mode"), phongo_readpreference_get_mode_string(intern->read_preference));
57+
zend_update_property_long(phongo_readpreference_ce, &intern->std, ZEND_STRL("maxStalenessSeconds"), mongoc_read_prefs_get_max_staleness_seconds(intern->read_preference));
58+
59+
bson = mongoc_read_prefs_get_tags(intern->read_preference);
60+
61+
if (!bson_empty0(bson)) {
62+
phongo_bson_state state;
63+
64+
PHONGO_BSON_INIT_STATE(state);
65+
state.map.root.type = PHONGO_TYPEMAP_NATIVE_ARRAY;
66+
67+
if (!phongo_bson_to_zval_ex(bson, &state)) {
68+
// Exception already thrown
69+
zval_ptr_dtor(&state.zchild);
70+
return;
71+
}
72+
73+
zend_update_property(phongo_readpreference_ce, &intern->std, ZEND_STRL("tags"), &state.zchild);
74+
zval_ptr_dtor(&state.zchild);
75+
} else {
76+
zend_update_property_null(phongo_readpreference_ce, &intern->std, ZEND_STRL("tags"));
77+
}
78+
79+
bson = mongoc_read_prefs_get_hedge(intern->read_preference);
80+
81+
if (!bson_empty0(bson)) {
82+
phongo_bson_state state;
83+
84+
PHONGO_BSON_INIT_STATE(state);
85+
86+
if (!phongo_bson_to_zval_ex(bson, &state)) {
87+
// Exception already thrown
88+
zval_ptr_dtor(&state.zchild);
89+
return;
90+
}
91+
92+
zend_update_property(phongo_readpreference_ce, &intern->std, ZEND_STRL("hedge"), &state.zchild);
93+
zval_ptr_dtor(&state.zchild);
94+
} else {
95+
zend_update_property_null(phongo_readpreference_ce, &intern->std, ZEND_STRL("hedge"));
96+
}
97+
}
98+
3499
/* Initialize the object from a HashTable and return whether it was successful.
35100
* An exception will be thrown on error. */
36101
static bool phongo_readpreference_init_from_hash(phongo_readpreference_t* intern, HashTable* props)
@@ -83,7 +148,7 @@ static bool phongo_readpreference_init_from_hash(phongo_readpreference_t* intern
83148

84149
mongoc_read_prefs_set_tags(intern->read_preference, tags);
85150
bson_destroy(tags);
86-
} else {
151+
} else if (Z_TYPE_P(tagSets) != IS_NULL) {
87152
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"tags\" field to be array", ZSTR_VAL(phongo_readpreference_ce->name));
88153
goto failure;
89154
}
@@ -134,7 +199,7 @@ static bool phongo_readpreference_init_from_hash(phongo_readpreference_t* intern
134199

135200
mongoc_read_prefs_set_hedge(intern->read_preference, hedge_doc);
136201
bson_destroy(hedge_doc);
137-
} else {
202+
} else if (Z_TYPE_P(hedge) != IS_NULL) {
138203
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "%s initialization requires \"hedge\" field to be an array or object", ZSTR_VAL(phongo_readpreference_ce->name));
139204
goto failure;
140205
}
@@ -145,6 +210,8 @@ static bool phongo_readpreference_init_from_hash(phongo_readpreference_t* intern
145210
goto failure;
146211
}
147212

213+
phongo_readpreference_update_properties(intern);
214+
148215
return true;
149216

150217
failure:
@@ -153,24 +220,6 @@ static bool phongo_readpreference_init_from_hash(phongo_readpreference_t* intern
153220
return false;
154221
}
155222

156-
static const char* phongo_readpreference_get_mode_string(const mongoc_read_prefs_t* read_prefs)
157-
{
158-
switch (mongoc_read_prefs_get_mode(read_prefs)) {
159-
case MONGOC_READ_PRIMARY:
160-
return PHONGO_READ_PRIMARY;
161-
case MONGOC_READ_PRIMARY_PREFERRED:
162-
return PHONGO_READ_PRIMARY_PREFERRED;
163-
case MONGOC_READ_SECONDARY:
164-
return PHONGO_READ_SECONDARY;
165-
case MONGOC_READ_SECONDARY_PREFERRED:
166-
return PHONGO_READ_SECONDARY_PREFERRED;
167-
case MONGOC_READ_NEAREST:
168-
return PHONGO_READ_NEAREST;
169-
default:
170-
return "";
171-
}
172-
}
173-
174223
/* Constructs a new ReadPreference */
175224
static PHP_METHOD(MongoDB_Driver_ReadPreference, __construct)
176225
{
@@ -281,6 +330,8 @@ static PHP_METHOD(MongoDB_Driver_ReadPreference, __construct)
281330
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Read preference is not valid");
282331
return;
283332
}
333+
334+
phongo_readpreference_update_properties(intern);
284335
}
285336

286337
static PHP_METHOD(MongoDB_Driver_ReadPreference, __set_state)
@@ -384,89 +435,34 @@ static PHP_METHOD(MongoDB_Driver_ReadPreference, getTagSets)
384435
}
385436
}
386437

387-
static HashTable* phongo_readpreference_get_properties_hash(zend_object* object, bool is_temp)
438+
static PHP_METHOD(MongoDB_Driver_ReadPreference, bsonSerialize)
388439
{
389-
phongo_readpreference_t* intern;
390-
HashTable* props;
391-
const bson_t* tags;
392-
const bson_t* hedge;
393-
394-
intern = Z_OBJ_READPREFERENCE(object);
395-
396-
PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_temp, intern, props, 4);
397-
398-
if (!intern->read_preference) {
399-
return props;
400-
}
440+
PHONGO_PARSE_PARAMETERS_NONE();
401441

402-
tags = mongoc_read_prefs_get_tags(intern->read_preference);
403-
hedge = mongoc_read_prefs_get_hedge(intern->read_preference);
442+
array_init_size(return_value, 4);
404443

405444
{
406-
zval z_mode;
407-
408-
ZVAL_STRING(&z_mode, phongo_readpreference_get_mode_string(intern->read_preference));
409-
zend_hash_str_update(props, "mode", sizeof("mode") - 1, &z_mode);
410-
}
411-
412-
if (!bson_empty0(tags)) {
413-
phongo_bson_state state;
414-
415-
/* Use PHONGO_TYPEMAP_NATIVE_ARRAY for the root type since tags is an
416-
* array; however, inner documents and arrays can use the default. */
417-
PHONGO_BSON_INIT_STATE(state);
418-
state.map.root.type = PHONGO_TYPEMAP_NATIVE_ARRAY;
419-
420-
if (!phongo_bson_to_zval_ex(tags, &state)) {
421-
zval_ptr_dtor(&state.zchild);
422-
goto done;
423-
}
424-
425-
zend_hash_str_update(props, "tags", sizeof("tags") - 1, &state.zchild);
426-
}
427-
428-
if (mongoc_read_prefs_get_max_staleness_seconds(intern->read_preference) != MONGOC_NO_MAX_STALENESS) {
429-
/* Note: valid values for maxStalesnessSeconds will not exceed the range
430-
* of 32-bit signed integers, so conditional encoding is not necessary. */
431-
long maxStalenessSeconds = mongoc_read_prefs_get_max_staleness_seconds(intern->read_preference);
432-
zval z_max_ss;
433-
434-
ZVAL_LONG(&z_max_ss, maxStalenessSeconds);
435-
zend_hash_str_update(props, "maxStalenessSeconds", sizeof("maxStalenessSeconds") - 1, &z_max_ss);
436-
}
437-
438-
if (!bson_empty0(hedge)) {
439-
phongo_bson_state state;
440-
441-
PHONGO_BSON_INIT_STATE(state);
445+
zend_string* string_key;
446+
zval* val;
447+
448+
ZEND_HASH_FOREACH_STR_KEY_VAL_IND(HASH_OF(getThis()), string_key, val)
449+
{
450+
if (
451+
(Z_TYPE_P(val) == IS_NULL) || (!strcmp(ZSTR_VAL(string_key), "maxStalenessSeconds") && Z_TYPE_P(val) == IS_LONG && Z_LVAL_P(val) == MONGOC_NO_MAX_STALENESS)) {
452+
continue;
453+
}
442454

443-
if (!phongo_bson_to_zval_ex(hedge, &state)) {
444-
zval_ptr_dtor(&state.zchild);
445-
goto done;
455+
// Increase the refcount of our zval, as add_assoc_zval takes ownership, leading to the property value being
456+
// freed once the return value goes out of scope
457+
Z_TRY_ADDREF_P(val);
458+
add_assoc_zval(return_value, ZSTR_VAL(string_key), val);
446459
}
447-
448-
zend_hash_str_update(props, "hedge", sizeof("hedge") - 1, &state.zchild);
460+
ZEND_HASH_FOREACH_END();
449461
}
450462

451-
done:
452-
return props;
453-
}
454-
455-
static PHP_METHOD(MongoDB_Driver_ReadPreference, bsonSerialize)
456-
{
457-
PHONGO_PARSE_PARAMETERS_NONE();
458-
459-
ZVAL_ARR(return_value, phongo_readpreference_get_properties_hash(Z_OBJ_P(getThis()), true));
460463
convert_to_object(return_value);
461464
}
462465

463-
static PHP_METHOD(MongoDB_Driver_ReadPreference, __serialize)
464-
{
465-
PHONGO_PARSE_PARAMETERS_NONE();
466-
467-
RETURN_ARR(phongo_readpreference_get_properties_hash(Z_OBJ_P(getThis()), true));
468-
}
469-
470466
static PHP_METHOD(MongoDB_Driver_ReadPreference, __unserialize)
471467
{
472468
zval* data;
@@ -487,11 +483,6 @@ static void phongo_readpreference_free_object(zend_object* object)
487483

488484
zend_object_std_dtor(&intern->std);
489485

490-
if (intern->properties) {
491-
zend_hash_destroy(intern->properties);
492-
FREE_HASHTABLE(intern->properties);
493-
}
494-
495486
if (intern->read_preference) {
496487
mongoc_read_prefs_destroy(intern->read_preference);
497488
}
@@ -509,15 +500,13 @@ static zend_object* phongo_readpreference_create_object(zend_class_entry* class_
509500
return &intern->std;
510501
}
511502

512-
static HashTable* phongo_readpreference_get_debug_info(zend_object* object, int* is_temp)
503+
static zval* phongo_readpreference_read_property(zend_object* zobj, zend_string* name, int type, void** cache_slot, zval* rv)
513504
{
514-
*is_temp = 1;
515-
return phongo_readpreference_get_properties_hash(object, true);
516-
}
505+
if (!strcmp(ZSTR_VAL(name), "hedge")) {
506+
php_error_docref(NULL, E_DEPRECATED, "Property MongoDB\\Driver\\ReadPreference::hedge is deprecated");
507+
}
517508

518-
static HashTable* phongo_readpreference_get_properties(zend_object* object)
519-
{
520-
return phongo_readpreference_get_properties_hash(object, false);
509+
return zend_std_read_property(zobj, name, type, cache_slot, rv);
521510
}
522511

523512
void phongo_readpreference_init_ce(INIT_FUNC_ARGS)
@@ -526,10 +515,9 @@ void phongo_readpreference_init_ce(INIT_FUNC_ARGS)
526515
phongo_readpreference_ce->create_object = phongo_readpreference_create_object;
527516

528517
memcpy(&phongo_handler_readpreference, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
529-
phongo_handler_readpreference.get_debug_info = phongo_readpreference_get_debug_info;
530-
phongo_handler_readpreference.get_properties = phongo_readpreference_get_properties;
531-
phongo_handler_readpreference.free_obj = phongo_readpreference_free_object;
532-
phongo_handler_readpreference.offset = XtOffsetOf(phongo_readpreference_t, std);
518+
phongo_handler_readpreference.read_property = phongo_readpreference_read_property;
519+
phongo_handler_readpreference.free_obj = phongo_readpreference_free_object;
520+
phongo_handler_readpreference.offset = XtOffsetOf(phongo_readpreference_t, std);
533521
}
534522

535523
void phongo_readpreference_init(zval* return_value, const mongoc_read_prefs_t* read_prefs)
@@ -540,6 +528,8 @@ void phongo_readpreference_init(zval* return_value, const mongoc_read_prefs_t* r
540528

541529
intern = Z_READPREFERENCE_OBJ_P(return_value);
542530
intern->read_preference = mongoc_read_prefs_copy(read_prefs);
531+
532+
phongo_readpreference_update_properties(intern);
543533
}
544534

545535
const mongoc_read_prefs_t* phongo_read_preference_from_zval(zval* zread_preference)

src/MongoDB/ReadPreference.stub.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ final class ReadPreference implements \MongoDB\BSON\Serializable
5151
*/
5252
public const SMALLEST_MAX_STALENESS_SECONDS = UNKNOWN;
5353

54+
public readonly string $mode;
55+
public readonly array|null $tags;
56+
public readonly int $maxStalenessSeconds;
57+
58+
/** @deprecated */
59+
public readonly object|null $hedge;
60+
5461
final public function __construct(string $mode, ?array $tagSets = null, ?array $options = null) {}
5562

5663
/** @deprecated Hedged reads are deprecated in MongoDB 8.0 and will be removed in a future release */
@@ -67,6 +74,4 @@ final public static function __set_state(array $properties): ReadPreference {}
6774
final public function bsonSerialize(): \stdClass {}
6875

6976
final public function __unserialize(array $data): void {}
70-
71-
final public function __serialize(): array {}
7277
}

src/MongoDB/ReadPreference_arginfo.h

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

src/phongo_structs.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,6 @@ typedef struct {
127127

128128
typedef struct {
129129
mongoc_read_prefs_t* read_preference;
130-
HashTable* properties;
131130
zend_object std;
132131
} phongo_readpreference_t;
133132

0 commit comments

Comments
 (0)