Skip to content

Commit c15d131

Browse files
committed
PHPC-1438: Expose session state
1 parent c598560 commit c15d131

File tree

3 files changed

+158
-0
lines changed

3 files changed

+158
-0
lines changed

src/MongoDB/Session.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@
2929

3030
zend_class_entry* php_phongo_session_ce;
3131

32+
#define PHONGO_TRANSACTION_NONE "none"
33+
#define PHONGO_TRANSACTION_STARTING "starting"
34+
#define PHONGO_TRANSACTION_IN_PROGRESS "in_progress"
35+
#define PHONGO_TRANSACTION_COMMITTED "committed"
36+
#define PHONGO_TRANSACTION_ABORTED "aborted"
37+
3238
#define SESSION_CHECK_LIVELINESS(i, m) \
3339
if (!(i)->client_session) { \
3440
phongo_throw_exception( \
@@ -93,6 +99,25 @@ static bool php_phongo_session_get_timestamp_parts(zval* obj, uint32_t* timestam
9399
return retval;
94100
}
95101

102+
static const char* php_phongo_get_transaction_state_string(mongoc_transaction_state_t state TSRMLS_DC)
103+
{
104+
switch (state) {
105+
case MONGOC_TRANSACTION_NONE:
106+
return PHONGO_TRANSACTION_NONE;
107+
case MONGOC_TRANSACTION_STARTING:
108+
return PHONGO_TRANSACTION_STARTING;
109+
case MONGOC_TRANSACTION_IN_PROGRESS:
110+
return PHONGO_TRANSACTION_IN_PROGRESS;
111+
case MONGOC_TRANSACTION_COMMITTED:
112+
return PHONGO_TRANSACTION_COMMITTED;
113+
case MONGOC_TRANSACTION_ABORTED:
114+
return PHONGO_TRANSACTION_ABORTED;
115+
default:
116+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Invalid transaction state %d given", (int) state);
117+
return NULL;
118+
}
119+
}
120+
96121
/* {{{ proto void MongoDB\Driver\Session::advanceClusterTime(array|object $clusterTime)
97122
Advances the cluster time for this Session */
98123
static PHP_METHOD(Session, advanceClusterTime)
@@ -343,6 +368,30 @@ static PHP_METHOD(Session, getTransactionOptions)
343368
}
344369
} /* }}} */
345370

371+
/* {{{ proto string MongoDB\Driver\Session::getTransactionState()
372+
Returns the current transaction state for this session */
373+
static PHP_METHOD(Session, getTransactionState)
374+
{
375+
php_phongo_session_t* intern;
376+
const char* state;
377+
378+
intern = Z_SESSION_OBJ_P(getThis());
379+
SESSION_CHECK_LIVELINESS(intern, "getTransactionState")
380+
381+
if (zend_parse_parameters_none() == FAILURE) {
382+
return;
383+
}
384+
385+
state = php_phongo_get_transaction_state_string(mongoc_client_session_get_transaction_state(intern->client_session) TSRMLS_CC);
386+
if (!state) {
387+
/* Exception already thrown */
388+
return;
389+
}
390+
391+
PHONGO_RETURN_STRING(state);
392+
} /* }}} */
393+
394+
346395
/* Creates a opts structure from an array optionally containing an RP, RC,
347396
* WC object, and/or maxCommitTimeMS int. Returns NULL if no options were found,
348397
* or there was an invalid option. If there was an invalid option or structure,
@@ -572,6 +621,7 @@ static zend_function_entry php_phongo_session_me[] = {
572621
PHP_ME(Session, getOperationTime, ai_Session_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
573622
PHP_ME(Session, getServer, ai_Session_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
574623
PHP_ME(Session, getTransactionOptions, ai_Session_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
624+
PHP_ME(Session, getTransactionState, ai_Session_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
575625
PHP_ME(Session, isInTransaction, ai_Session_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
576626
PHP_ME(Session, startTransaction, ai_Session_startTransaction, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
577627
ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_Session_void, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)
@@ -760,6 +810,12 @@ void php_phongo_session_init_ce(INIT_FUNC_ARGS) /* {{{ */
760810
php_phongo_handler_session.free_obj = php_phongo_session_free_object;
761811
php_phongo_handler_session.offset = XtOffsetOf(php_phongo_session_t, std);
762812
#endif
813+
814+
zend_declare_class_constant_string(php_phongo_session_ce, ZEND_STRL("TRANSACTION_NONE"), PHONGO_TRANSACTION_NONE TSRMLS_CC);
815+
zend_declare_class_constant_string(php_phongo_session_ce, ZEND_STRL("TRANSACTION_STARTING"), PHONGO_TRANSACTION_STARTING TSRMLS_CC);
816+
zend_declare_class_constant_string(php_phongo_session_ce, ZEND_STRL("TRANSACTION_IN_PROGRESS"), PHONGO_TRANSACTION_IN_PROGRESS TSRMLS_CC);
817+
zend_declare_class_constant_string(php_phongo_session_ce, ZEND_STRL("TRANSACTION_COMMITTED"), PHONGO_TRANSACTION_COMMITTED TSRMLS_CC);
818+
zend_declare_class_constant_string(php_phongo_session_ce, ZEND_STRL("TRANSACTION_ABORTED"), PHONGO_TRANSACTION_ABORTED TSRMLS_CC);
763819
} /* }}} */
764820

765821
/*

tests/session/session-constants.phpt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
MongoDB\Driver\Session constants
3+
--FILE--
4+
<?php
5+
6+
var_dump(MongoDB\Driver\Session::TRANSACTION_NONE);
7+
var_dump(MongoDB\Driver\Session::TRANSACTION_STARTING);
8+
var_dump(MongoDB\Driver\Session::TRANSACTION_IN_PROGRESS);
9+
var_dump(MongoDB\Driver\Session::TRANSACTION_COMMITTED);
10+
var_dump(MongoDB\Driver\Session::TRANSACTION_ABORTED);
11+
12+
?>
13+
===DONE===
14+
<?php exit(0); ?>
15+
--EXPECTF--
16+
string(4) "none"
17+
string(8) "starting"
18+
string(11) "in_progress"
19+
string(9) "committed"
20+
string(7) "aborted"
21+
===DONE===
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
--TEST--
2+
MongoDB\Driver\Session::getTransactionState()
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
5+
<?php skip_if_not_libmongoc_crypto() ?>
6+
<?php skip_if_no_transactions(); ?>
7+
<?php skip_if_not_clean(); ?>
8+
--FILE--
9+
<?php
10+
require_once __DIR__ . "/../utils/basic.inc";
11+
12+
$manager = new MongoDB\Driver\Manager(URI);
13+
14+
/* Create collections as that can't be (automatically) done in a transaction */
15+
$cmd = new \MongoDB\Driver\Command([
16+
'create' => COLLECTION_NAME,
17+
]);
18+
$manager->executeCommand(DATABASE_NAME, $cmd);
19+
20+
/* Start a session */
21+
$session = $manager->startSession();
22+
23+
echo "Test case: Empty transaction, and aborted empty transaction\n";
24+
var_dump($session->getTransactionState());
25+
$session->startTransaction();
26+
var_dump($session->getTransactionState());
27+
$session->abortTransaction();
28+
var_dump($session->getTransactionState());
29+
echo "\n";
30+
31+
echo "Test case: Empty transaction, and committed empty transaction\n";
32+
$session->startTransaction();
33+
var_dump($session->getTransactionState());
34+
$session->commitTransaction();
35+
var_dump($session->getTransactionState());
36+
echo "\n";
37+
38+
echo "Test case: Aborted transaction with one operation\n";
39+
$session->startTransaction();
40+
var_dump($session->getTransactionState());
41+
$bw = new \MongoDB\Driver\BulkWrite();
42+
$bw->insert( [ '_id' => 0, 'msg' => 'Initial Value' ] );
43+
$manager->executeBulkWrite(NS, $bw, ['session' => $session]);
44+
var_dump($session->getTransactionState());
45+
$session->abortTransaction();
46+
var_dump($session->getTransactionState());
47+
echo "\n";
48+
49+
echo "Test case: Committed transaction with one operation\n";
50+
$session->startTransaction();
51+
var_dump($session->getTransactionState());
52+
$bw = new \MongoDB\Driver\BulkWrite();
53+
$bw->insert( [ '_id' => 0, 'msg' => 'Initial Value' ] );
54+
$manager->executeBulkWrite(NS, $bw, ['session' => $session]);
55+
var_dump($session->getTransactionState());
56+
$session->commitTransaction();
57+
var_dump($session->getTransactionState());
58+
59+
?>
60+
===DONE===
61+
<?php exit(0); ?>
62+
--EXPECTF--
63+
Test case: Empty transaction, and aborted empty transaction
64+
string(4) "none"
65+
string(8) "starting"
66+
string(7) "aborted"
67+
68+
Test case: Empty transaction, and committed empty transaction
69+
string(8) "starting"
70+
string(9) "committed"
71+
72+
Test case: Aborted transaction with one operation
73+
string(8) "starting"
74+
string(11) "in_progress"
75+
string(7) "aborted"
76+
77+
Test case: Committed transaction with one operation
78+
string(8) "starting"
79+
string(11) "in_progress"
80+
string(9) "committed"
81+
===DONE===

0 commit comments

Comments
 (0)