@@ -242,6 +242,40 @@ static void php_phongo_manager_prep_uri_options(zval *options TSRMLS_DC) /* {{{
242242 return ;
243243} /* }}} */
244244
245+ /* Selects a server for an execute method. If "for_writes" is true, a primary
246+ * will be selected. Otherwise, a read preference will be used to select the
247+ * server. If zreadPreference is NULL, the client's read preference will be
248+ * used.
249+ *
250+ * On success, server_id will be set and the function will return true;
251+ * otherwise, false is returned and an exception is thrown. */
252+ static bool php_phongo_manager_select_server (bool for_writes , zval * zreadPreference , mongoc_client_t * client , uint32_t * server_id TSRMLS_DC ) /* {{{ */
253+ {
254+ const mongoc_read_prefs_t * read_preference = NULL ;
255+ mongoc_server_description_t * selected_server ;
256+ bson_error_t error ;
257+
258+ if (!for_writes ) {
259+ read_preference = zreadPreference ? phongo_read_preference_from_zval (zreadPreference TSRMLS_CC ) : mongoc_client_get_read_prefs (client );
260+ }
261+
262+ selected_server = mongoc_client_select_server (client , for_writes , read_preference , & error );
263+
264+ if (selected_server ) {
265+ * server_id = mongoc_server_description_id (selected_server );
266+ mongoc_server_description_destroy (selected_server );
267+
268+ return true;
269+ }
270+
271+ /* Check for connection related exceptions */
272+ if (!EG (exception )) {
273+ phongo_throw_exception_from_bson_error_t (& error TSRMLS_CC );
274+ }
275+
276+ return false;
277+ } /* }}} */
278+
245279/* {{{ proto void MongoDB\Driver\Manager::__construct([string $uri = "mongodb://127.0.0.1/"[, array $options = array()[, array $driverOptions = array()]]])
246280 Constructs a new Manager */
247281static PHP_METHOD (Manager , __construct )
@@ -292,6 +326,9 @@ static PHP_METHOD(Manager, executeCommand)
292326 phongo_zpp_char_len db_len ;
293327 zval * command ;
294328 zval * options = NULL ;
329+ bool free_options = false;
330+ zval * zreadPreference = NULL ;
331+ uint32_t server_id = 0 ;
295332 DECLARE_RETURN_VALUE_USED
296333 SUPPRESS_UNUSED_WARNING (return_value_ptr )
297334
@@ -301,7 +338,24 @@ static PHP_METHOD(Manager, executeCommand)
301338
302339 intern = Z_MANAGER_OBJ_P (getThis ());
303340
304- phongo_execute_command (intern -> client , PHONGO_COMMAND_RAW , db , command , options , -1 , return_value , return_value_used TSRMLS_CC );
341+ options = php_phongo_prep_legacy_option (options , "readPreference" , & free_options TSRMLS_CC );
342+
343+ if (!phongo_parse_read_preference (options , & zreadPreference TSRMLS_CC )) {
344+ /* Exception should already have been thrown */
345+ goto cleanup ;
346+ }
347+
348+ if (!php_phongo_manager_select_server (false, zreadPreference , intern -> client , & server_id TSRMLS_CC )) {
349+ /* Exception should already have been thrown */
350+ goto cleanup ;
351+ }
352+
353+ phongo_execute_command (intern -> client , PHONGO_COMMAND_RAW , db , command , options , server_id , return_value , return_value_used TSRMLS_CC );
354+
355+ cleanup :
356+ if (free_options ) {
357+ php_phongo_prep_legacy_option_free (options TSRMLS_CC );
358+ }
305359} /* }}} */
306360
307361/* {{{ proto MongoDB\Driver\Cursor MongoDB\Driver\Manager::executeReadCommand(string $db, MongoDB\Driver\Command $command[, array $options = null])
@@ -313,6 +367,8 @@ static PHP_METHOD(Manager, executeReadCommand)
313367 phongo_zpp_char_len db_len ;
314368 zval * command ;
315369 zval * options = NULL ;
370+ zval * zreadPreference = NULL ;
371+ uint32_t server_id = 0 ;
316372 DECLARE_RETURN_VALUE_USED
317373 SUPPRESS_UNUSED_WARNING (return_value_ptr )
318374
@@ -322,7 +378,17 @@ static PHP_METHOD(Manager, executeReadCommand)
322378
323379 intern = Z_MANAGER_OBJ_P (getThis ());
324380
325- phongo_execute_command (intern -> client , PHONGO_COMMAND_READ , db , command , options , -1 , return_value , return_value_used TSRMLS_CC );
381+ if (!phongo_parse_read_preference (options , & zreadPreference TSRMLS_CC )) {
382+ /* Exception should already have been thrown */
383+ return ;
384+ }
385+
386+ if (!php_phongo_manager_select_server (false, zreadPreference , intern -> client , & server_id TSRMLS_CC )) {
387+ /* Exception should already have been thrown */
388+ return ;
389+ }
390+
391+ phongo_execute_command (intern -> client , PHONGO_COMMAND_READ , db , command , options , server_id , return_value , return_value_used TSRMLS_CC );
326392} /* }}} */
327393
328394/* {{{ proto MongoDB\Driver\Cursor MongoDB\Driver\Manager::executeWriteCommand(string $db, MongoDB\Driver\Command $command[, array $options = null])
@@ -334,6 +400,7 @@ static PHP_METHOD(Manager, executeWriteCommand)
334400 phongo_zpp_char_len db_len ;
335401 zval * command ;
336402 zval * options = NULL ;
403+ uint32_t server_id = 0 ;
337404 DECLARE_RETURN_VALUE_USED
338405 SUPPRESS_UNUSED_WARNING (return_value_ptr )
339406
@@ -343,7 +410,12 @@ static PHP_METHOD(Manager, executeWriteCommand)
343410
344411 intern = Z_MANAGER_OBJ_P (getThis ());
345412
346- phongo_execute_command (intern -> client , PHONGO_COMMAND_WRITE , db , command , options , -1 , return_value , return_value_used TSRMLS_CC );
413+ if (!php_phongo_manager_select_server (true, NULL , intern -> client , & server_id TSRMLS_CC )) {
414+ /* Exception should already have been thrown */
415+ return ;
416+ }
417+
418+ phongo_execute_command (intern -> client , PHONGO_COMMAND_WRITE , db , command , options , server_id , return_value , return_value_used TSRMLS_CC );
347419} /* }}} */
348420
349421/* {{{ proto MongoDB\Driver\Cursor MongoDB\Driver\Manager::executeReadWriteCommand(string $db, MongoDB\Driver\Command $command[, array $options = null])
@@ -355,6 +427,7 @@ static PHP_METHOD(Manager, executeReadWriteCommand)
355427 phongo_zpp_char_len db_len ;
356428 zval * command ;
357429 zval * options = NULL ;
430+ uint32_t server_id = 0 ;
358431 DECLARE_RETURN_VALUE_USED
359432 SUPPRESS_UNUSED_WARNING (return_value_ptr )
360433
@@ -364,7 +437,12 @@ static PHP_METHOD(Manager, executeReadWriteCommand)
364437
365438 intern = Z_MANAGER_OBJ_P (getThis ());
366439
367- phongo_execute_command (intern -> client , PHONGO_COMMAND_READ_WRITE , db , command , options , -1 , return_value , return_value_used TSRMLS_CC );
440+ if (!php_phongo_manager_select_server (true, NULL , intern -> client , & server_id TSRMLS_CC )) {
441+ /* Exception should already have been thrown */
442+ return ;
443+ }
444+
445+ phongo_execute_command (intern -> client , PHONGO_COMMAND_READ_WRITE , db , command , options , server_id , return_value , return_value_used TSRMLS_CC );
368446} /* }}} */
369447
370448/* {{{ proto MongoDB\Driver\Cursor MongoDB\Driver\Manager::executeQuery(string $namespace, MongoDB\Driver\Query $query[, array $options = null])
@@ -376,6 +454,9 @@ static PHP_METHOD(Manager, executeQuery)
376454 phongo_zpp_char_len namespace_len ;
377455 zval * query ;
378456 zval * options = NULL ;
457+ bool free_options = false;
458+ zval * zreadPreference = NULL ;
459+ uint32_t server_id = 0 ;
379460 DECLARE_RETURN_VALUE_USED
380461 SUPPRESS_UNUSED_WARNING (return_value_ptr )
381462
@@ -385,7 +466,24 @@ static PHP_METHOD(Manager, executeQuery)
385466
386467 intern = Z_MANAGER_OBJ_P (getThis ());
387468
388- phongo_execute_query (intern -> client , namespace , query , options , -1 , return_value , return_value_used TSRMLS_CC );
469+ options = php_phongo_prep_legacy_option (options , "readPreference" , & free_options TSRMLS_CC );
470+
471+ if (!phongo_parse_read_preference (options , & zreadPreference TSRMLS_CC )) {
472+ /* Exception should already have been thrown */
473+ goto cleanup ;
474+ }
475+
476+ if (!php_phongo_manager_select_server (false, zreadPreference , intern -> client , & server_id TSRMLS_CC )) {
477+ /* Exception should already have been thrown */
478+ goto cleanup ;
479+ }
480+
481+ phongo_execute_query (intern -> client , namespace , query , options , server_id , return_value , return_value_used TSRMLS_CC );
482+
483+ cleanup :
484+ if (free_options ) {
485+ php_phongo_prep_legacy_option_free (options TSRMLS_CC );
486+ }
389487} /* }}} */
390488
391489/* {{{ proto MongoDB\Driver\WriteResult MongoDB\Driver\Manager::executeBulkWrite(string $namespace, MongoDB\Driver\BulkWrite $zbulk[, array $options = null])
@@ -396,8 +494,10 @@ static PHP_METHOD(Manager, executeBulkWrite)
396494 char * namespace ;
397495 phongo_zpp_char_len namespace_len ;
398496 zval * zbulk ;
399- zval * options = NULL ;
400497 php_phongo_bulkwrite_t * bulk ;
498+ zval * options = NULL ;
499+ bool free_options = false;
500+ uint32_t server_id = 0 ;
401501 DECLARE_RETURN_VALUE_USED
402502 SUPPRESS_UNUSED_WARNING (return_value_ptr )
403503
@@ -408,7 +508,19 @@ static PHP_METHOD(Manager, executeBulkWrite)
408508 intern = Z_MANAGER_OBJ_P (getThis ());
409509 bulk = Z_BULKWRITE_OBJ_P (zbulk );
410510
411- phongo_execute_bulk_write (intern -> client , namespace , bulk , options , -1 , return_value , return_value_used TSRMLS_CC );
511+ options = php_phongo_prep_legacy_option (options , "writeConcern" , & free_options TSRMLS_CC );
512+
513+ if (!php_phongo_manager_select_server (true, NULL , intern -> client , & server_id TSRMLS_CC )) {
514+ /* Exception should already have been thrown */
515+ goto cleanup ;
516+ }
517+
518+ phongo_execute_bulk_write (intern -> client , namespace , bulk , options , server_id , return_value , return_value_used TSRMLS_CC );
519+
520+ cleanup :
521+ if (free_options ) {
522+ php_phongo_prep_legacy_option_free (options TSRMLS_CC );
523+ }
412524} /* }}} */
413525
414526/* {{{ proto MongoDB\Driver\ReadConcern MongoDB\Driver\Manager::getReadConcern()
@@ -511,9 +623,7 @@ static PHP_METHOD(Manager, selectServer)
511623{
512624 php_phongo_manager_t * intern ;
513625 zval * zreadPreference = NULL ;
514- const mongoc_read_prefs_t * readPreference ;
515- bson_error_t error ;
516- mongoc_server_description_t * selected_server = NULL ;
626+ uint32_t server_id = 0 ;
517627 SUPPRESS_UNUSED_WARNING (return_value_ptr ) SUPPRESS_UNUSED_WARNING (return_value_used )
518628
519629
@@ -523,19 +633,12 @@ static PHP_METHOD(Manager, selectServer)
523633 return ;
524634 }
525635
526- readPreference = phongo_read_preference_from_zval (zreadPreference TSRMLS_CC );
527- selected_server = mongoc_client_select_server (intern -> client , false, readPreference , & error );
528- if (selected_server ) {
529- phongo_server_init (return_value , intern -> client , mongoc_server_description_id (selected_server ) TSRMLS_CC );
530- mongoc_server_description_destroy (selected_server );
531- } else {
532- /* Check for connection related exceptions */
533- if (EG (exception )) {
534- return ;
535- }
536-
537- phongo_throw_exception_from_bson_error_t (& error TSRMLS_CC );
636+ if (!php_phongo_manager_select_server (false, zreadPreference , intern -> client , & server_id TSRMLS_CC )) {
637+ /* Exception should already have been thrown */
638+ return ;
538639 }
640+
641+ phongo_server_init (return_value , intern -> client , server_id TSRMLS_CC );
539642} /* }}} */
540643
541644/* {{{ proto MongoDB\Driver\Session MongoDB\Driver\Manager::startSession([array $options = null])
0 commit comments