Skip to content

Commit 79469c4

Browse files
committed
Merge pull request #1014
2 parents 64259e2 + d750c70 commit 79469c4

File tree

84 files changed

+1168
-142
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+1168
-142
lines changed

php_phongo.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ bool phongo_parse_read_preference(zval* options, zval** zreadPreference TSRMLS_D
604604
* not NULL, the option will be appended. If zsession is not NULL, it will be
605605
* assigned to the option. On error, false is returned and an exception is
606606
* thrown. */
607-
static bool phongo_parse_session(zval* options, mongoc_client_t* client, bson_t* mongoc_opts, zval** zsession TSRMLS_DC) /* {{{ */
607+
bool phongo_parse_session(zval* options, mongoc_client_t* client, bson_t* mongoc_opts, zval** zsession TSRMLS_DC) /* {{{ */
608608
{
609609
zval* option = NULL;
610610
const mongoc_client_session_t* client_session;

php_phongo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ const mongoc_write_concern_t* phongo_write_concern_from_zval(zval* zwrite_concer
147147
php_phongo_server_description_type_t php_phongo_server_description_type(mongoc_server_description_t* sd);
148148

149149
bool phongo_parse_read_preference(zval* options, zval** zreadPreference TSRMLS_DC);
150+
bool phongo_parse_session(zval* options, mongoc_client_t* client, bson_t* mongoc_opts, zval** zsession TSRMLS_DC);
150151

151152
zval* php_phongo_prep_legacy_option(zval* options, const char* key, bool* allocated TSRMLS_DC);
152153
void php_phongo_prep_legacy_option_free(zval* options TSRMLS_DC);

scripts/presets/travis/sharded_clusters/cluster.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,13 @@
6969
"logappend": true,
7070
"port": 4300,
7171
"bind_ip_all": true
72+
},
73+
{
74+
"logpath": "/tmp/MO/SHARDED/ROUTER/4301/mongod.log",
75+
"ipv6": true,
76+
"logappend": true,
77+
"port": 4301,
78+
"bind_ip_all": true
7279
}
7380
]
7481
}

scripts/presets/travis/sharded_clusters/cluster_replset.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,13 @@
9191
"logappend": true,
9292
"port": 4430,
9393
"bind_ip_all": true
94+
},
95+
{
96+
"logpath": "/tmp/MO/SHARDED-RS/ROUTER/4431/mongod.log",
97+
"ipv6": true,
98+
"logappend": true,
99+
"port": 4431,
100+
"bind_ip_all": true
94101
}
95102
]
96103
}

src/LIBMONGOC_VERSION_CURRENT

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.15.0
1+
1.15.1-20190828+gitcf50d6315a

src/MongoDB/Manager.c

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

src/MongoDB/Session.c

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,6 @@ zend_class_entry* php_phongo_session_ce;
3838
return; \
3939
}
4040

41-
static bool php_phongo_topology_is_sharded_cluster(mongoc_client_t* client)
42-
{
43-
mongoc_server_description_t* sd;
44-
bool ret;
45-
46-
sd = mongoc_client_select_server(client, true, NULL, NULL);
47-
ret = (sd && !strcmp(mongoc_server_description_type(sd), php_phongo_server_description_type_map[PHONGO_SERVER_MONGOS].name));
48-
mongoc_server_description_destroy(sd);
49-
50-
return ret;
51-
}
52-
5341
static bool php_phongo_session_get_timestamp_parts(zval* obj, uint32_t* timestamp, uint32_t* increment TSRMLS_DC)
5442
{
5543
bool retval = false;
@@ -246,6 +234,30 @@ static PHP_METHOD(Session, getOperationTime)
246234
php_phongo_new_timestamp_from_increment_and_timestamp(return_value, increment, timestamp TSRMLS_CC);
247235
} /* }}} */
248236

237+
/* {{{ proto MongoDB\Driver\Server|null MongoDB\Driver\Session::getServer()
238+
Returns the server this session is pinned to */
239+
static PHP_METHOD(Session, getServer)
240+
{
241+
php_phongo_session_t* intern;
242+
uint32_t server_id = 0;
243+
244+
intern = Z_SESSION_OBJ_P(getThis());
245+
SESSION_CHECK_LIVELINESS(intern, "getServer")
246+
247+
if (zend_parse_parameters_none() == FAILURE) {
248+
return;
249+
}
250+
251+
server_id = mongoc_client_session_get_server_id(intern->client_session);
252+
253+
/* For sessions without a pinned server, 0 is returned. */
254+
if (!server_id) {
255+
RETURN_NULL();
256+
}
257+
258+
phongo_server_init(return_value, mongoc_client_session_get_client(intern->client_session), server_id TSRMLS_CC);
259+
} /* }}} */
260+
249261
/* Creates a opts structure from an array optionally containing an RP, RC,
250262
* WC object, and/or maxCommitTimeMS int. Returns NULL if no options were found,
251263
* or there was an invalid option. If there was an invalid option or structure,
@@ -366,11 +378,6 @@ static PHP_METHOD(Session, startTransaction)
366378
return;
367379
}
368380

369-
if (php_phongo_topology_is_sharded_cluster(mongoc_client_session_get_client(intern->client_session))) {
370-
phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "PHP MongoDB driver %s does not support running multi-document transactions on sharded clusters", PHP_MONGODB_VERSION);
371-
return;
372-
}
373-
374381
if (!mongoc_client_session_start_transaction(intern->client_session, txn_options, &error)) {
375382
phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC);
376383
}
@@ -478,6 +485,7 @@ static zend_function_entry php_phongo_session_me[] = {
478485
PHP_ME(Session, getClusterTime, ai_Session_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
479486
PHP_ME(Session, getLogicalSessionId, ai_Session_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
480487
PHP_ME(Session, getOperationTime, ai_Session_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
488+
PHP_ME(Session, getServer, ai_Session_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
481489
PHP_ME(Session, isInTransaction, ai_Session_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
482490
PHP_ME(Session, startTransaction, ai_Session_startTransaction, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
483491
ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_Session_void, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)
@@ -618,6 +626,30 @@ static HashTable* php_phongo_session_get_debug_info(zval* object, int* is_temp T
618626
ADD_ASSOC_NULL_EX(&retval, "operationTime");
619627
}
620628

629+
if (intern->client_session) {
630+
uint32_t server_id = mongoc_client_session_get_server_id(intern->client_session);
631+
632+
if (server_id) {
633+
634+
#if PHP_VERSION_ID >= 70000
635+
zval server;
636+
637+
phongo_server_init(&server, mongoc_client_session_get_client(intern->client_session), server_id TSRMLS_CC);
638+
ADD_ASSOC_ZVAL_EX(&retval, "server", &server);
639+
#else
640+
zval* server = NULL;
641+
642+
MAKE_STD_ZVAL(server);
643+
phongo_server_init(server, mongoc_client_session_get_client(intern->client_session), server_id TSRMLS_CC);
644+
ADD_ASSOC_ZVAL_EX(&retval, "server", server);
645+
#endif
646+
} else {
647+
ADD_ASSOC_NULL_EX(&retval, "server");
648+
}
649+
} else {
650+
ADD_ASSOC_NULL_EX(&retval, "server");
651+
}
652+
621653
return Z_ARRVAL(retval);
622654
} /* }}} */
623655
/* }}} */

tests/causal-consistency/causal-consistency-001.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Causal consistency: new session has no operation time
33
--SKIPIF--
44
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
55
<?php skip_if_not_libmongoc_crypto(); ?>
6-
<?php skip_if_not_replica_set(); ?>
6+
<?php skip_if_not_replica_set_or_mongos_with_replica_set(); ?>
77
<?php skip_if_server_version('<', '3.6'); ?>
88
--FILE--
99
<?php

tests/causal-consistency/causal-consistency-002.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Causal consistency: first read in session does not include afterClusterTime
33
--SKIPIF--
44
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
55
<?php skip_if_not_libmongoc_crypto(); ?>
6-
<?php skip_if_not_replica_set(); ?>
6+
<?php skip_if_not_replica_set_or_mongos_with_replica_set(); ?>
77
<?php skip_if_server_version('<', '3.6'); ?>
88
--FILE--
99
<?php

0 commit comments

Comments
 (0)