@@ -254,15 +254,28 @@ static void php_phongo_manager_prep_uri_options(zval* options TSRMLS_DC) /* {{{
254254/* Selects a server for an execute method. If "for_writes" is true, a primary
255255 * will be selected. Otherwise, a read preference will be used to select the
256256 * server. If zreadPreference is NULL, the client's read preference will be
257- * used.
257+ * used. If zsession is a session object in a sharded transaction, the session
258+ * will be checked whether it is pinned to a server. If so, that server will be
259+ * selected. Otherwise, server selection
258260 *
259261 * On success, server_id will be set and the function will return true;
260262 * otherwise, false is returned and an exception is thrown. */
261- static bool php_phongo_manager_select_server (bool for_writes , zval * zreadPreference , mongoc_client_t * client , uint32_t * server_id TSRMLS_DC ) /* {{{ */
263+ static bool php_phongo_manager_select_server (bool for_writes , zval * zreadPreference , zval * zsession , mongoc_client_t * client , uint32_t * server_id TSRMLS_DC ) /* {{{ */
262264{
263- const mongoc_read_prefs_t * read_preference = NULL ;
264265 mongoc_server_description_t * selected_server ;
265- bson_error_t error = { 0 };
266+ const mongoc_read_prefs_t * read_preference = NULL ;
267+ bson_error_t error = { 0 };
268+
269+ if (zsession ) {
270+ const mongoc_client_session_t * session = Z_SESSION_OBJ_P (zsession )-> client_session ;
271+
272+ /* Attempt to fetch server pinned to session */
273+ if (mongoc_client_session_get_server_id (session ) > 0 ) {
274+ * server_id = mongoc_client_session_get_server_id (session );
275+
276+ return true;
277+ }
278+ }
266279
267280 if (!for_writes ) {
268281 read_preference = zreadPreference ? phongo_read_preference_from_zval (zreadPreference TSRMLS_CC ) : mongoc_client_get_read_prefs (client );
@@ -336,6 +349,7 @@ static PHP_METHOD(Manager, executeCommand)
336349 zval * options = NULL ;
337350 bool free_options = false;
338351 zval * zreadPreference = NULL ;
352+ zval * zsession = NULL ;
339353 uint32_t server_id = 0 ;
340354 DECLARE_RETURN_VALUE_USED
341355
@@ -347,12 +361,17 @@ static PHP_METHOD(Manager, executeCommand)
347361
348362 options = php_phongo_prep_legacy_option (options , "readPreference" , & free_options TSRMLS_CC );
349363
364+ if (!phongo_parse_session (options , intern -> client , NULL , & zsession TSRMLS_CC )) {
365+ /* Exception should already have been thrown */
366+ goto cleanup ;
367+ }
368+
350369 if (!phongo_parse_read_preference (options , & zreadPreference TSRMLS_CC )) {
351370 /* Exception should already have been thrown */
352371 goto cleanup ;
353372 }
354373
355- if (!php_phongo_manager_select_server (false, zreadPreference , intern -> client , & server_id TSRMLS_CC )) {
374+ if (!php_phongo_manager_select_server (false, zreadPreference , zsession , intern -> client , & server_id TSRMLS_CC )) {
356375 /* Exception should already have been thrown */
357376 goto cleanup ;
358377 }
@@ -376,6 +395,7 @@ static PHP_METHOD(Manager, executeReadCommand)
376395 zval * options = NULL ;
377396 zval * zreadPreference = NULL ;
378397 uint32_t server_id = 0 ;
398+ zval * zsession = NULL ;
379399 DECLARE_RETURN_VALUE_USED
380400
381401 if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "sO|a!" , & db , & db_len , & command , php_phongo_command_ce , & options ) == FAILURE ) {
@@ -384,12 +404,17 @@ static PHP_METHOD(Manager, executeReadCommand)
384404
385405 intern = Z_MANAGER_OBJ_P (getThis ());
386406
407+ if (!phongo_parse_session (options , intern -> client , NULL , & zsession TSRMLS_CC )) {
408+ /* Exception should already have been thrown */
409+ return ;
410+ }
411+
387412 if (!phongo_parse_read_preference (options , & zreadPreference TSRMLS_CC )) {
388413 /* Exception should already have been thrown */
389414 return ;
390415 }
391416
392- if (!php_phongo_manager_select_server (false, zreadPreference , intern -> client , & server_id TSRMLS_CC )) {
417+ if (!php_phongo_manager_select_server (false, zreadPreference , zsession , intern -> client , & server_id TSRMLS_CC )) {
393418 /* Exception should already have been thrown */
394419 return ;
395420 }
@@ -407,6 +432,7 @@ static PHP_METHOD(Manager, executeWriteCommand)
407432 zval * command ;
408433 zval * options = NULL ;
409434 uint32_t server_id = 0 ;
435+ zval * zsession = NULL ;
410436 DECLARE_RETURN_VALUE_USED
411437
412438 if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "sO|a!" , & db , & db_len , & command , php_phongo_command_ce , & options ) == FAILURE ) {
@@ -415,7 +441,12 @@ static PHP_METHOD(Manager, executeWriteCommand)
415441
416442 intern = Z_MANAGER_OBJ_P (getThis ());
417443
418- if (!php_phongo_manager_select_server (true, NULL , intern -> client , & server_id TSRMLS_CC )) {
444+ if (!phongo_parse_session (options , intern -> client , NULL , & zsession TSRMLS_CC )) {
445+ /* Exception should already have been thrown */
446+ return ;
447+ }
448+
449+ if (!php_phongo_manager_select_server (true, NULL , zsession , intern -> client , & server_id TSRMLS_CC )) {
419450 /* Exception should already have been thrown */
420451 return ;
421452 }
@@ -433,6 +464,7 @@ static PHP_METHOD(Manager, executeReadWriteCommand)
433464 zval * command ;
434465 zval * options = NULL ;
435466 uint32_t server_id = 0 ;
467+ zval * zsession = NULL ;
436468 DECLARE_RETURN_VALUE_USED
437469
438470 if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "sO|a!" , & db , & db_len , & command , php_phongo_command_ce , & options ) == FAILURE ) {
@@ -441,7 +473,12 @@ static PHP_METHOD(Manager, executeReadWriteCommand)
441473
442474 intern = Z_MANAGER_OBJ_P (getThis ());
443475
444- if (!php_phongo_manager_select_server (true, NULL , intern -> client , & server_id TSRMLS_CC )) {
476+ if (!phongo_parse_session (options , intern -> client , NULL , & zsession TSRMLS_CC )) {
477+ /* Exception should already have been thrown */
478+ return ;
479+ }
480+
481+ if (!php_phongo_manager_select_server (true, NULL , zsession , intern -> client , & server_id TSRMLS_CC )) {
445482 /* Exception should already have been thrown */
446483 return ;
447484 }
@@ -461,6 +498,7 @@ static PHP_METHOD(Manager, executeQuery)
461498 bool free_options = false;
462499 zval * zreadPreference = NULL ;
463500 uint32_t server_id = 0 ;
501+ zval * zsession = NULL ;
464502 DECLARE_RETURN_VALUE_USED
465503
466504 if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "sO|z!" , & namespace , & namespace_len , & query , php_phongo_query_ce , & options ) == FAILURE ) {
@@ -471,12 +509,17 @@ static PHP_METHOD(Manager, executeQuery)
471509
472510 options = php_phongo_prep_legacy_option (options , "readPreference" , & free_options TSRMLS_CC );
473511
512+ if (!phongo_parse_session (options , intern -> client , NULL , & zsession TSRMLS_CC )) {
513+ /* Exception should already have been thrown */
514+ goto cleanup ;
515+ }
516+
474517 if (!phongo_parse_read_preference (options , & zreadPreference TSRMLS_CC )) {
475518 /* Exception should already have been thrown */
476519 goto cleanup ;
477520 }
478521
479- if (!php_phongo_manager_select_server (false, zreadPreference , intern -> client , & server_id TSRMLS_CC )) {
522+ if (!php_phongo_manager_select_server (false, zreadPreference , zsession , intern -> client , & server_id TSRMLS_CC )) {
480523 /* Exception should already have been thrown */
481524 goto cleanup ;
482525 }
@@ -501,6 +544,7 @@ static PHP_METHOD(Manager, executeBulkWrite)
501544 zval * options = NULL ;
502545 bool free_options = false;
503546 uint32_t server_id = 0 ;
547+ zval * zsession = NULL ;
504548 DECLARE_RETURN_VALUE_USED
505549
506550 if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "sO|z!" , & namespace , & namespace_len , & zbulk , php_phongo_bulkwrite_ce , & options ) == FAILURE ) {
@@ -512,7 +556,12 @@ static PHP_METHOD(Manager, executeBulkWrite)
512556
513557 options = php_phongo_prep_legacy_option (options , "writeConcern" , & free_options TSRMLS_CC );
514558
515- if (!php_phongo_manager_select_server (true, NULL , intern -> client , & server_id TSRMLS_CC )) {
559+ if (!phongo_parse_session (options , intern -> client , NULL , & zsession TSRMLS_CC )) {
560+ /* Exception should already have been thrown */
561+ return ;
562+ }
563+
564+ if (!php_phongo_manager_select_server (true, NULL , zsession , intern -> client , & server_id TSRMLS_CC )) {
516565 /* Exception should already have been thrown */
517566 goto cleanup ;
518567 }
@@ -628,7 +677,7 @@ static PHP_METHOD(Manager, selectServer)
628677 return ;
629678 }
630679
631- if (!php_phongo_manager_select_server (false, zreadPreference , intern -> client , & server_id TSRMLS_CC )) {
680+ if (!php_phongo_manager_select_server (false, zreadPreference , NULL , intern -> client , & server_id TSRMLS_CC )) {
632681 /* Exception should already have been thrown */
633682 return ;
634683 }
0 commit comments