|
28 | 28 |
|
29 | 29 | zend_class_entry* php_phongo_readpreference_ce;
|
30 | 30 |
|
| 31 | +/* Initialize the object from a HashTable and return whether it was successful. |
| 32 | + * An exception will be thrown on error. */ |
| 33 | +static bool php_phongo_readpreference_init_from_hash(php_phongo_readpreference_t* intern, HashTable* props TSRMLS_DC) /* {{{ */ |
| 34 | +{ |
| 35 | +#if PHP_VERSION_ID >= 70000 |
| 36 | + zval *mode, *tagSets, *maxStalenessSeconds; |
| 37 | + |
| 38 | + if ((mode = zend_hash_str_find(props, "mode", sizeof("mode") - 1)) && Z_TYPE_P(mode) == IS_STRING) { |
| 39 | + if (strcasecmp(Z_STRVAL_P(mode), "primary") == 0) { |
| 40 | + intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_PRIMARY); |
| 41 | + } else if (strcasecmp(Z_STRVAL_P(mode), "primaryPreferred") == 0) { |
| 42 | + intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_PRIMARY_PREFERRED); |
| 43 | + } else if (strcasecmp(Z_STRVAL_P(mode), "secondary") == 0) { |
| 44 | + intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_SECONDARY); |
| 45 | + } else if (strcasecmp(Z_STRVAL_P(mode), "secondaryPreferred") == 0) { |
| 46 | + intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_SECONDARY_PREFERRED); |
| 47 | + } else if (strcasecmp(Z_STRVAL_P(mode), "nearest") == 0) { |
| 48 | + intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_NEAREST); |
| 49 | + } else { |
| 50 | + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires specific values for \"mode\" string field", ZSTR_VAL(php_phongo_readpreference_ce->name)); |
| 51 | + return false; |
| 52 | + } |
| 53 | + } else { |
| 54 | + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"mode\" field to be string", ZSTR_VAL(php_phongo_readpreference_ce->name)); |
| 55 | + return false; |
| 56 | + } |
| 57 | + |
| 58 | + if ((tagSets = zend_hash_str_find(props, "tags", sizeof("tags") - 1))) { |
| 59 | + if (Z_TYPE_P(tagSets) == IS_ARRAY) { |
| 60 | + bson_t* tags = bson_new(); |
| 61 | + |
| 62 | + php_phongo_read_preference_prep_tagsets(tagSets TSRMLS_CC); |
| 63 | + php_phongo_zval_to_bson(tagSets, PHONGO_BSON_NONE, (bson_t*) tags, NULL TSRMLS_CC); |
| 64 | + |
| 65 | + if (!php_phongo_read_preference_tags_are_valid(tags)) { |
| 66 | + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"tags\" array field to have zero or more documents", ZSTR_VAL(php_phongo_writeconcern_ce->name)); |
| 67 | + bson_destroy(tags); |
| 68 | + goto failure; |
| 69 | + } |
| 70 | + |
| 71 | + if (!bson_empty(tags) && (mongoc_read_prefs_get_mode(intern->read_preference) == MONGOC_READ_PRIMARY)) { |
| 72 | + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"tags\" array field to not be present with \"primary\" mode", ZSTR_VAL(php_phongo_writeconcern_ce->name)); |
| 73 | + bson_destroy(tags); |
| 74 | + goto failure; |
| 75 | + } |
| 76 | + |
| 77 | + mongoc_read_prefs_set_tags(intern->read_preference, tags); |
| 78 | + bson_destroy(tags); |
| 79 | + } else { |
| 80 | + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"tags\" field to be array", ZSTR_VAL(php_phongo_writeconcern_ce->name)); |
| 81 | + goto failure; |
| 82 | + } |
| 83 | + } |
| 84 | + |
| 85 | + if ((maxStalenessSeconds = zend_hash_str_find(props, "maxStalenessSeconds", sizeof("maxStalenessSeconds") - 1))) { |
| 86 | + if (Z_TYPE_P(maxStalenessSeconds) == IS_LONG) { |
| 87 | + if (Z_LVAL_P(maxStalenessSeconds) < MONGOC_SMALLEST_MAX_STALENESS_SECONDS) { |
| 88 | + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"maxStalenessSeconds\" integer field to be >= %d", ZSTR_VAL(php_phongo_writeconcern_ce->name), MONGOC_SMALLEST_MAX_STALENESS_SECONDS); |
| 89 | + goto failure; |
| 90 | + } |
| 91 | + if (Z_LVAL_P(maxStalenessSeconds) > INT32_MAX) { |
| 92 | + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"maxStalenessSeconds\" integer field to be <= %" PRId32, ZSTR_VAL(php_phongo_writeconcern_ce->name), INT32_MAX); |
| 93 | + goto failure; |
| 94 | + } |
| 95 | + if (mongoc_read_prefs_get_mode(intern->read_preference) == MONGOC_READ_PRIMARY) { |
| 96 | + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"maxStalenessSeconds\" array field to not be present with \"primary\" mode", ZSTR_VAL(php_phongo_writeconcern_ce->name)); |
| 97 | + goto failure; |
| 98 | + } |
| 99 | + |
| 100 | + mongoc_read_prefs_set_max_staleness_seconds(intern->read_preference, Z_LVAL_P(maxStalenessSeconds)); |
| 101 | + } else { |
| 102 | + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"maxStalenessSeconds\" field to be integer", ZSTR_VAL(php_phongo_writeconcern_ce->name)); |
| 103 | + goto failure; |
| 104 | + } |
| 105 | + } |
| 106 | +#else |
| 107 | + zval **mode, **tagSets, **maxStalenessSeconds; |
| 108 | + |
| 109 | + if (zend_hash_find(props, "mode", sizeof("mode"), (void**) &mode) == SUCCESS && Z_TYPE_PP(mode) == IS_STRING) { |
| 110 | + if (strcasecmp(Z_STRVAL_PP(mode), "primary") == 0) { |
| 111 | + intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_PRIMARY); |
| 112 | + } else if (strcasecmp(Z_STRVAL_PP(mode), "primaryPreferred") == 0) { |
| 113 | + intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_PRIMARY_PREFERRED); |
| 114 | + } else if (strcasecmp(Z_STRVAL_PP(mode), "secondary") == 0) { |
| 115 | + intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_SECONDARY); |
| 116 | + } else if (strcasecmp(Z_STRVAL_PP(mode), "secondaryPreferred") == 0) { |
| 117 | + intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_SECONDARY_PREFERRED); |
| 118 | + } else if (strcasecmp(Z_STRVAL_PP(mode), "nearest") == 0) { |
| 119 | + intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_NEAREST); |
| 120 | + } else { |
| 121 | + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires specific values for \"mode\" string field", ZSTR_VAL(php_phongo_readpreference_ce->name)); |
| 122 | + return false; |
| 123 | + } |
| 124 | + } else { |
| 125 | + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"mode\" field to be string", ZSTR_VAL(php_phongo_readpreference_ce->name)); |
| 126 | + return false; |
| 127 | + } |
| 128 | + |
| 129 | + if (zend_hash_find(props, "tags", sizeof("tags"), (void**) &tagSets) == SUCCESS) { |
| 130 | + if (Z_TYPE_PP(tagSets) == IS_ARRAY) { |
| 131 | + bson_t* tags = bson_new(); |
| 132 | + |
| 133 | + php_phongo_read_preference_prep_tagsets(*tagSets TSRMLS_CC); |
| 134 | + php_phongo_zval_to_bson(*tagSets, PHONGO_BSON_NONE, (bson_t*) tags, NULL TSRMLS_CC); |
| 135 | + |
| 136 | + if (!php_phongo_read_preference_tags_are_valid(tags)) { |
| 137 | + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"tags\" array field to have zero or more documents", ZSTR_VAL(php_phongo_writeconcern_ce->name)); |
| 138 | + bson_destroy(tags); |
| 139 | + goto failure; |
| 140 | + } |
| 141 | + |
| 142 | + if (!bson_empty(tags) && (mongoc_read_prefs_get_mode(intern->read_preference) == MONGOC_READ_PRIMARY)) { |
| 143 | + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"tags\" array field to not be present with \"primary\" mode", ZSTR_VAL(php_phongo_writeconcern_ce->name)); |
| 144 | + bson_destroy(tags); |
| 145 | + goto failure; |
| 146 | + } |
| 147 | + |
| 148 | + mongoc_read_prefs_set_tags(intern->read_preference, tags); |
| 149 | + bson_destroy(tags); |
| 150 | + } else { |
| 151 | + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"tags\" field to be array", ZSTR_VAL(php_phongo_writeconcern_ce->name)); |
| 152 | + goto failure; |
| 153 | + } |
| 154 | + } |
| 155 | + |
| 156 | + if (zend_hash_find(props, "maxStalenessSeconds", sizeof("maxStalenessSeconds"), (void**) &maxStalenessSeconds) == SUCCESS) { |
| 157 | + if (Z_TYPE_PP(maxStalenessSeconds) == IS_LONG) { |
| 158 | + if (Z_LVAL_PP(maxStalenessSeconds) < MONGOC_SMALLEST_MAX_STALENESS_SECONDS) { |
| 159 | + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"maxStalenessSeconds\" integer field to be >= %d", ZSTR_VAL(php_phongo_writeconcern_ce->name), MONGOC_SMALLEST_MAX_STALENESS_SECONDS); |
| 160 | + goto failure; |
| 161 | + } |
| 162 | + if (Z_LVAL_PP(maxStalenessSeconds) > INT32_MAX) { |
| 163 | + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"maxStalenessSeconds\" integer field to be <= %" PRId32, ZSTR_VAL(php_phongo_writeconcern_ce->name), INT32_MAX); |
| 164 | + goto failure; |
| 165 | + } |
| 166 | + if (mongoc_read_prefs_get_mode(intern->read_preference) == MONGOC_READ_PRIMARY) { |
| 167 | + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"maxStalenessSeconds\" array field to not be present with \"primary\" mode", ZSTR_VAL(php_phongo_writeconcern_ce->name)); |
| 168 | + goto failure; |
| 169 | + } |
| 170 | + |
| 171 | + mongoc_read_prefs_set_max_staleness_seconds(intern->read_preference, Z_LVAL_PP(maxStalenessSeconds)); |
| 172 | + } else { |
| 173 | + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"maxStalenessSeconds\" field to be integer", ZSTR_VAL(php_phongo_writeconcern_ce->name)); |
| 174 | + goto failure; |
| 175 | + } |
| 176 | + } |
| 177 | +#endif |
| 178 | + |
| 179 | + return true; |
| 180 | + |
| 181 | +failure: |
| 182 | + mongoc_read_prefs_destroy(intern->read_preference); |
| 183 | + intern->read_preference = NULL; |
| 184 | + return false; |
| 185 | +} /* }}} */ |
| 186 | + |
31 | 187 | /* {{{ proto void MongoDB\Driver\ReadPreference::__construct(int|string $mode[, array $tagSets = array()[, array $options = array()]])
|
32 | 188 | Constructs a new ReadPreference */
|
33 | 189 | static PHP_METHOD(ReadPreference, __construct)
|
@@ -131,6 +287,26 @@ static PHP_METHOD(ReadPreference, __construct)
|
131 | 287 | }
|
132 | 288 | } /* }}} */
|
133 | 289 |
|
| 290 | +/* {{{ proto void MongoDB\BSON\ReadPreference::__set_state(array $properties) |
| 291 | +*/ |
| 292 | +static PHP_METHOD(ReadPreference, __set_state) |
| 293 | +{ |
| 294 | + php_phongo_readpreference_t* intern; |
| 295 | + HashTable* props; |
| 296 | + zval* array; |
| 297 | + |
| 298 | + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) { |
| 299 | + RETURN_FALSE; |
| 300 | + } |
| 301 | + |
| 302 | + object_init_ex(return_value, php_phongo_readpreference_ce); |
| 303 | + |
| 304 | + intern = Z_READPREFERENCE_OBJ_P(return_value); |
| 305 | + props = Z_ARRVAL_P(array); |
| 306 | + |
| 307 | + php_phongo_readpreference_init_from_hash(intern, props TSRMLS_CC); |
| 308 | +} /* }}} */ |
| 309 | + |
134 | 310 | /* {{{ proto integer MongoDB\Driver\ReadPreference::getMaxStalenessSeconds()
|
135 | 311 | Returns the ReadPreference maxStalenessSeconds value */
|
136 | 312 | static PHP_METHOD(ReadPreference, getMaxStalenessSeconds)
|
@@ -302,12 +478,17 @@ ZEND_BEGIN_ARG_INFO_EX(ai_ReadPreference___construct, 0, 0, 1)
|
302 | 478 | ZEND_ARG_ARRAY_INFO(0, options, 1)
|
303 | 479 | ZEND_END_ARG_INFO()
|
304 | 480 |
|
| 481 | +ZEND_BEGIN_ARG_INFO_EX(ai_ReadPreference___set_state, 0, 0, 1) |
| 482 | + ZEND_ARG_ARRAY_INFO(0, properties, 0) |
| 483 | +ZEND_END_ARG_INFO() |
| 484 | + |
305 | 485 | ZEND_BEGIN_ARG_INFO_EX(ai_ReadPreference_void, 0, 0, 0)
|
306 | 486 | ZEND_END_ARG_INFO()
|
307 | 487 |
|
308 | 488 | static zend_function_entry php_phongo_readpreference_me[] = {
|
309 | 489 | /* clang-format off */
|
310 | 490 | PHP_ME(ReadPreference, __construct, ai_ReadPreference___construct, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
|
| 491 | + PHP_ME(ReadPreference, __set_state, ai_ReadPreference___set_state, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) |
311 | 492 | PHP_ME(ReadPreference, getMaxStalenessSeconds, ai_ReadPreference_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
|
312 | 493 | PHP_ME(ReadPreference, getMode, ai_ReadPreference_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
|
313 | 494 | PHP_ME(ReadPreference, getTagSets, ai_ReadPreference_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
|
@@ -356,7 +537,7 @@ static phongo_create_object_retval php_phongo_readpreference_create_object(zend_
|
356 | 537 | #else
|
357 | 538 | {
|
358 | 539 | zend_object_value retval;
|
359 |
| - retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_readpreference_free_object, NULL TSRMLS_CC); |
| 540 | + retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_readpreference_free_object, NULL TSRMLS_CC); |
360 | 541 | retval.handlers = &php_phongo_handler_readpreference;
|
361 | 542 |
|
362 | 543 | return retval;
|
|
0 commit comments