Skip to content

Commit be8c925

Browse files
committed
Merged pull request #933
2 parents cc317b3 + 9cbb01a commit be8c925

11 files changed

+764
-3
lines changed

src/MongoDB/ReadConcern.c

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,48 @@
2626

2727
zend_class_entry* php_phongo_readconcern_ce;
2828

29+
/* Initialize the object from a HashTable and return whether it was successful.
30+
* An exception will be thrown on error. */
31+
static bool php_phongo_readconcern_init_from_hash(php_phongo_readconcern_t* intern, HashTable* props TSRMLS_DC) /* {{{ */
32+
{
33+
#if PHP_VERSION_ID >= 70000
34+
zval* level;
35+
36+
intern->read_concern = mongoc_read_concern_new();
37+
38+
if ((level = zend_hash_str_find(props, "level", sizeof("level") - 1))) {
39+
if (Z_TYPE_P(level) == IS_STRING) {
40+
mongoc_read_concern_set_level(intern->read_concern, Z_STRVAL_P(level));
41+
return true;
42+
}
43+
44+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"level\" string field", ZSTR_VAL(php_phongo_readconcern_ce->name));
45+
goto failure;
46+
}
47+
#else
48+
zval** level;
49+
50+
intern->read_concern = mongoc_read_concern_new();
51+
52+
if (zend_hash_find(props, "level", sizeof("level"), (void**) &level) == SUCCESS) {
53+
if (Z_TYPE_PP(level) == IS_STRING) {
54+
mongoc_read_concern_set_level(intern->read_concern, Z_STRVAL_PP(level));
55+
return true;
56+
}
57+
58+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"level\" string field", ZSTR_VAL(php_phongo_readconcern_ce->name));
59+
goto failure;
60+
}
61+
#endif
62+
63+
return true;
64+
65+
failure:
66+
mongoc_read_concern_destroy(intern->read_concern);
67+
intern->read_concern = NULL;
68+
return false;
69+
} /* }}} */
70+
2971
/* {{{ proto void MongoDB\Driver\ReadConcern::__construct([string $level])
3072
Constructs a new ReadConcern */
3173
static PHP_METHOD(ReadConcern, __construct)
@@ -51,6 +93,26 @@ static PHP_METHOD(ReadConcern, __construct)
5193
}
5294
} /* }}} */
5395

96+
/* {{{ proto void MongoDB\BSON\ReadConcern::__set_state(array $properties)
97+
*/
98+
static PHP_METHOD(ReadConcern, __set_state)
99+
{
100+
php_phongo_readconcern_t* intern;
101+
HashTable* props;
102+
zval* array;
103+
104+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) {
105+
RETURN_FALSE;
106+
}
107+
108+
object_init_ex(return_value, php_phongo_readconcern_ce);
109+
110+
intern = Z_READCONCERN_OBJ_P(return_value);
111+
props = Z_ARRVAL_P(array);
112+
113+
php_phongo_readconcern_init_from_hash(intern, props TSRMLS_CC);
114+
} /* }}} */
115+
54116
/* {{{ proto string|null MongoDB\Driver\ReadConcern::getLevel()
55117
Returns the ReadConcern "level" option */
56118
static PHP_METHOD(ReadConcern, getLevel)
@@ -140,12 +202,17 @@ ZEND_BEGIN_ARG_INFO_EX(ai_ReadConcern___construct, 0, 0, 0)
140202
ZEND_ARG_INFO(0, level)
141203
ZEND_END_ARG_INFO()
142204

205+
ZEND_BEGIN_ARG_INFO_EX(ai_ReadConcern___set_state, 0, 0, 1)
206+
ZEND_ARG_ARRAY_INFO(0, properties, 0)
207+
ZEND_END_ARG_INFO()
208+
143209
ZEND_BEGIN_ARG_INFO_EX(ai_ReadConcern_void, 0, 0, 0)
144210
ZEND_END_ARG_INFO()
145211

146212
static zend_function_entry php_phongo_readconcern_me[] = {
147213
/* clang-format off */
148214
PHP_ME(ReadConcern, __construct, ai_ReadConcern___construct, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
215+
PHP_ME(ReadConcern, __set_state, ai_ReadConcern___set_state, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
149216
PHP_ME(ReadConcern, getLevel, ai_ReadConcern_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
150217
PHP_ME(ReadConcern, isDefault, ai_ReadConcern_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
151218
PHP_ME(ReadConcern, bsonSerialize, ai_ReadConcern_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
@@ -175,7 +242,7 @@ static void php_phongo_readconcern_free_object(phongo_free_object_arg* object TS
175242
#if PHP_VERSION_ID < 70000
176243
efree(intern);
177244
#endif
178-
} /* }}} */
245+
}
179246

180247
static phongo_create_object_retval php_phongo_readconcern_create_object(zend_class_entry* class_type TSRMLS_DC) /* {{{ */
181248
{

src/MongoDB/ReadPreference.c

Lines changed: 182 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,162 @@
2828

2929
zend_class_entry* php_phongo_readpreference_ce;
3030

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+
31187
/* {{{ proto void MongoDB\Driver\ReadPreference::__construct(int|string $mode[, array $tagSets = array()[, array $options = array()]])
32188
Constructs a new ReadPreference */
33189
static PHP_METHOD(ReadPreference, __construct)
@@ -131,6 +287,26 @@ static PHP_METHOD(ReadPreference, __construct)
131287
}
132288
} /* }}} */
133289

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+
134310
/* {{{ proto integer MongoDB\Driver\ReadPreference::getMaxStalenessSeconds()
135311
Returns the ReadPreference maxStalenessSeconds value */
136312
static PHP_METHOD(ReadPreference, getMaxStalenessSeconds)
@@ -302,12 +478,17 @@ ZEND_BEGIN_ARG_INFO_EX(ai_ReadPreference___construct, 0, 0, 1)
302478
ZEND_ARG_ARRAY_INFO(0, options, 1)
303479
ZEND_END_ARG_INFO()
304480

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+
305485
ZEND_BEGIN_ARG_INFO_EX(ai_ReadPreference_void, 0, 0, 0)
306486
ZEND_END_ARG_INFO()
307487

308488
static zend_function_entry php_phongo_readpreference_me[] = {
309489
/* clang-format off */
310490
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)
311492
PHP_ME(ReadPreference, getMaxStalenessSeconds, ai_ReadPreference_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
312493
PHP_ME(ReadPreference, getMode, ai_ReadPreference_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
313494
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_
356537
#else
357538
{
358539
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);
360541
retval.handlers = &php_phongo_handler_readpreference;
361542

362543
return retval;

0 commit comments

Comments
 (0)