Skip to content

Commit 4f8c20b

Browse files
committed
Merge pull request #680
2 parents d39bf88 + b2d85bf commit 4f8c20b

17 files changed

+880
-9
lines changed

config.m4

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ if test "$MONGODB" != "no"; then
190190
src/MongoDB/ReadConcern.c \
191191
src/MongoDB/ReadPreference.c \
192192
src/MongoDB/Server.c \
193+
src/MongoDB/Session.c \
193194
src/MongoDB/WriteConcern.c \
194195
src/MongoDB/WriteConcernError.c \
195196
src/MongoDB/WriteError.c \

config.w32

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ if (PHP_MONGODB != "no") {
8585
EXTENSION("mongodb", "php_phongo.c phongo_compat.c", null, PHP_MONGODB_CFLAGS);
8686
ADD_SOURCES(configure_module_dirname + "/src", "bson.c bson-encode.c", "mongodb");
8787
ADD_SOURCES(configure_module_dirname + "/src/BSON", "Binary.c BinaryInterface.c DBPointer.c Decimal128.c Decimal128Interface.c Javascript.c JavascriptInterface.c MaxKey.c MaxKeyInterface.c MinKey.c MinKeyInterface.c ObjectId.c ObjectIdInterface.c Persistable.c Regex.c RegexInterface.c Serializable.c Symbol.c Timestamp.c TimestampInterface.c Type.c Undefined.c Unserializable.c UTCDateTime.c UTCDateTimeInterface.c functions.c", "mongodb");
88-
ADD_SOURCES(configure_module_dirname + "/src/MongoDB", "BulkWrite.c Command.c Cursor.c CursorId.c Manager.c Query.c ReadConcern.c ReadPreference.c Server.c WriteConcern.c WriteConcernError.c WriteError.c WriteResult.c", "mongodb");
88+
ADD_SOURCES(configure_module_dirname + "/src/MongoDB", "BulkWrite.c Command.c Cursor.c CursorId.c Manager.c Query.c ReadConcern.c ReadPreference.c Server.c Session.c WriteConcern.c WriteConcernError.c WriteError.c WriteResult.c", "mongodb");
8989
ADD_SOURCES(configure_module_dirname + "/src/MongoDB/Exception", "AuthenticationException.c BulkWriteException.c ConnectionException.c ConnectionTimeoutException.c Exception.c ExecutionTimeoutException.c InvalidArgumentException.c LogicException.c RuntimeException.c SSLConnectionException.c UnexpectedValueException.c WriteException.c", "mongodb");
9090
ADD_SOURCES(configure_module_dirname + "/src/MongoDB/Monitoring", "CommandFailedEvent.c CommandStartedEvent.c CommandSubscriber.c CommandSucceededEvent.c Subscriber.c functions.c", "mongodb");
9191
ADD_SOURCES(configure_module_dirname + "/src/libbson/src/bson", PHP_MONGODB_BSON_SOURCES, "mongodb");

php_phongo.c

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,17 @@ void phongo_server_init(zval *return_value, mongoc_client_t *client, int server_
306306
}
307307
/* }}} */
308308

309+
void phongo_session_init(zval *return_value, mongoc_client_session_t *client_session TSRMLS_DC) /* {{{ */
310+
{
311+
php_phongo_session_t *session;
312+
313+
object_init_ex(return_value, php_phongo_session_ce);
314+
315+
session = Z_SESSION_OBJ_P(return_value);
316+
session->client_session = client_session;
317+
}
318+
/* }}} */
319+
309320
void phongo_readconcern_init(zval *return_value, const mongoc_read_concern_t *read_concern TSRMLS_DC) /* {{{ */
310321
{
311322
php_phongo_readconcern_t *intern;
@@ -527,6 +538,34 @@ static bool process_read_preference(zval *option, bson_t *mongoc_opts, zval **zr
527538
return true;
528539
}
529540

541+
static bool process_session(zval *option, bson_t *mongoc_opts, zval **zsession, mongoc_client_t *client TSRMLS_DC)
542+
{
543+
const mongoc_client_session_t *client_session;
544+
545+
if (Z_TYPE_P(option) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(option), php_phongo_session_ce TSRMLS_CC)) {
546+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"session\" option to be %s, %s given", ZSTR_VAL(php_phongo_session_ce->name), PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(option));
547+
return false;
548+
}
549+
550+
client_session = Z_SESSION_OBJ_P(option)->client_session;
551+
552+
if (client != mongoc_client_session_get_client(client_session)) {
553+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Cannot use Session started from a different Manager");
554+
return false;
555+
}
556+
557+
if (!mongoc_client_session_append(Z_SESSION_OBJ_P(option)->client_session, mongoc_opts, NULL)) {
558+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error appending \"session\" option");
559+
return false;
560+
}
561+
562+
if (zsession) {
563+
*zsession = option;
564+
}
565+
566+
return true;
567+
}
568+
530569
static bool process_write_concern(zval *option, bson_t *mongoc_opts, zval **zwriteConcern TSRMLS_DC)
531570
{
532571
if (Z_TYPE_P(option) == IS_OBJECT && instanceof_function(Z_OBJCE_P(option), php_phongo_writeconcern_ce TSRMLS_CC)) {
@@ -550,7 +589,7 @@ static bool process_write_concern(zval *option, bson_t *mongoc_opts, zval **zwri
550589
return true;
551590
}
552591

553-
static int phongo_execute_parse_options(mongoc_client_t* client, int server_id, zval *driver_options, int type, bson_t *mongoc_opts, zval **zreadPreference, zval **zwriteConcern TSRMLS_DC)
592+
static int phongo_execute_parse_options(mongoc_client_t* client, int server_id, zval *driver_options, int type, bson_t *mongoc_opts, zval **zreadPreference, zval **zwriteConcern, zval **zsession TSRMLS_DC)
554593
{
555594
if (driver_options && Z_TYPE_P(driver_options) == IS_ARRAY) {
556595
HashTable *ht_data = HASH_OF(driver_options);
@@ -573,6 +612,10 @@ static int phongo_execute_parse_options(mongoc_client_t* client, int server_id,
573612
if (!process_read_preference(driver_option, mongoc_opts, zreadPreference, client, server_id)) {
574613
return false;
575614
}
615+
} else if ((!strcmp(ZSTR_VAL(string_key), "session"))) {
616+
if (!process_session(driver_option, mongoc_opts, zsession, client)) {
617+
return false;
618+
}
576619
} else if ((!strcasecmp(ZSTR_VAL(string_key), "writeConcern")) && (type & PHONGO_COMMAND_WRITE)) {
577620
if (!process_write_concern(driver_option, mongoc_opts, zwriteConcern)) {
578621
return false;
@@ -606,6 +649,10 @@ static int phongo_execute_parse_options(mongoc_client_t* client, int server_id,
606649
if (!process_read_preference(*driver_option, mongoc_opts, zreadPreference, client, server_id TSRMLS_CC)) {
607650
return false;
608651
}
652+
} else if ((!strcasecmp(ZSTR_VAL(string_key), "session"))) {
653+
if (!process_session(*driver_option, mongoc_opts, zsession, client TSRMLS_CC)) {
654+
return false;
655+
}
609656
} else if ((!strcasecmp(string_key, "writeConcern")) && (type & PHONGO_COMMAND_WRITE)) {
610657
if (!process_write_concern(*driver_option, mongoc_opts, zwriteConcern TSRMLS_CC)) {
611658
return false;
@@ -628,6 +675,7 @@ bool phongo_execute_bulk_write(mongoc_client_t *client, const char *namespace, p
628675
mongoc_bulk_operation_t *bulk = bulk_write->bulk;
629676
php_phongo_writeresult_t *writeresult;
630677
zval *zwriteConcern = NULL;
678+
zval *zsession = NULL;
631679
const mongoc_write_concern_t *write_concern;
632680
bson_t opts = BSON_INITIALIZER;
633681

@@ -644,7 +692,7 @@ bool phongo_execute_bulk_write(mongoc_client_t *client, const char *namespace, p
644692
/* FIXME: Legacy way of specifying the writeConcern option into this function */
645693
if (options && Z_TYPE_P(options) == IS_OBJECT && instanceof_function(Z_OBJCE_P(options), php_phongo_writeconcern_ce TSRMLS_CC)) {
646694
zwriteConcern = options;
647-
} else if (!phongo_execute_parse_options(client, server_id, options, PHONGO_COMMAND_WRITE, &opts, NULL, &zwriteConcern TSRMLS_CC)) {
695+
} else if (!phongo_execute_parse_options(client, server_id, options, PHONGO_COMMAND_WRITE, &opts, NULL, &zwriteConcern, &zsession TSRMLS_CC)) {
648696
bson_destroy(&opts);
649697
return false;
650698
}
@@ -655,6 +703,10 @@ bool phongo_execute_bulk_write(mongoc_client_t *client, const char *namespace, p
655703
mongoc_bulk_operation_set_collection(bulk, bulk_write->collection);
656704
mongoc_bulk_operation_set_client(bulk, client);
657705

706+
if (zsession) {
707+
mongoc_bulk_operation_set_client_session(bulk, Z_SESSION_OBJ_P(zsession)->client_session);
708+
}
709+
658710
/* If a write concern was not specified, libmongoc will use the client's
659711
* write concern; however, we should still fetch it for the write result. */
660712
write_concern = phongo_write_concern_from_zval(zwriteConcern TSRMLS_CC);
@@ -736,7 +788,6 @@ int phongo_execute_query(mongoc_client_t *client, const char *namespace, zval *z
736788
char *collname;
737789
mongoc_collection_t *collection;
738790
zval *zreadPreference = NULL;
739-
bson_t opts = BSON_INITIALIZER;
740791

741792
if (!phongo_split_namespace(namespace, &dbname, &collname)) {
742793
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s: %s", "Invalid namespace provided", namespace);
@@ -755,13 +806,10 @@ int phongo_execute_query(mongoc_client_t *client, const char *namespace, zval *z
755806
/* FIXME: Legacy way of specifying the readPreference option into this function */
756807
if (options && Z_TYPE_P(options) == IS_OBJECT && instanceof_function(Z_OBJCE_P(options), php_phongo_readpreference_ce TSRMLS_CC)) {
757808
zreadPreference = options;
758-
} else if (!phongo_execute_parse_options(client, server_id, options, PHONGO_COMMAND_READ, &opts, &zreadPreference, NULL TSRMLS_CC)) {
759-
bson_destroy(&opts);
809+
} else if (!phongo_execute_parse_options(client, server_id, options, PHONGO_COMMAND_READ, query->opts, &zreadPreference, NULL, NULL TSRMLS_CC)) {
760810
return false;
761811
}
762812

763-
bson_destroy(&opts);
764-
765813
cursor = mongoc_collection_find_with_opts(collection, query->filter, query->opts, phongo_read_preference_from_zval(zreadPreference TSRMLS_CC));
766814
mongoc_collection_destroy(collection);
767815

@@ -819,7 +867,7 @@ int phongo_execute_command(mongoc_client_t *client, php_phongo_command_type_t ty
819867
/* FIXME: Legacy way of specifying the readPreference option into this function */
820868
if (options && Z_TYPE_P(options) == IS_OBJECT && instanceof_function(Z_OBJCE_P(options), php_phongo_readpreference_ce TSRMLS_CC)) {
821869
zreadPreference = options;
822-
} else if (!phongo_execute_parse_options(client, server_id, options, type, &opts, &zreadPreference, NULL TSRMLS_CC)) {
870+
} else if (!phongo_execute_parse_options(client, server_id, options, type, &opts, &zreadPreference, NULL, NULL TSRMLS_CC)) {
823871
return false;
824872
}
825873

@@ -2693,6 +2741,7 @@ PHP_MINIT_FUNCTION(mongodb)
26932741
php_phongo_readconcern_init_ce(INIT_FUNC_ARGS_PASSTHRU);
26942742
php_phongo_readpreference_init_ce(INIT_FUNC_ARGS_PASSTHRU);
26952743
php_phongo_server_init_ce(INIT_FUNC_ARGS_PASSTHRU);
2744+
php_phongo_session_init_ce(INIT_FUNC_ARGS_PASSTHRU);
26962745
php_phongo_writeconcern_init_ce(INIT_FUNC_ARGS_PASSTHRU);
26972746
php_phongo_writeconcernerror_init_ce(INIT_FUNC_ARGS_PASSTHRU);
26982747
php_phongo_writeerror_init_ce(INIT_FUNC_ARGS_PASSTHRU);

php_phongo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ typedef enum {
126126
zend_object_handlers *phongo_get_std_object_handlers(void);
127127

128128
void phongo_server_init (zval *return_value, mongoc_client_t *client, int server_id TSRMLS_DC);
129+
void phongo_session_init (zval *return_value, mongoc_client_session_t *client_session TSRMLS_DC);
129130
void phongo_readconcern_init (zval *return_value, const mongoc_read_concern_t *read_concern TSRMLS_DC);
130131
void phongo_readpreference_init (zval *return_value, const mongoc_read_prefs_t *read_prefs TSRMLS_DC);
131132
void phongo_writeconcern_init (zval *return_value, const mongoc_write_concern_t *write_concern TSRMLS_DC);

php_phongo_classes.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ static inline php_phongo_readpreference_t* php_readpreference_fetch_object(zend_
5252
static inline php_phongo_server_t* php_server_fetch_object(zend_object *obj) {
5353
return (php_phongo_server_t *)((char *)obj - XtOffsetOf(php_phongo_server_t, std));
5454
}
55+
static inline php_phongo_session_t* php_session_fetch_object(zend_object *obj) {
56+
return (php_phongo_session_t *)((char *)obj - XtOffsetOf(php_phongo_session_t, std));
57+
}
5558
static inline php_phongo_writeconcern_t* php_writeconcern_fetch_object(zend_object *obj) {
5659
return (php_phongo_writeconcern_t *)((char *)obj - XtOffsetOf(php_phongo_writeconcern_t, std));
5760
}
@@ -118,6 +121,7 @@ static inline php_phongo_commandsucceededevent_t* php_commandsucceededevent_fetc
118121
# define Z_READCONCERN_OBJ_P(zv) (php_readconcern_fetch_object(Z_OBJ_P(zv)))
119122
# define Z_READPREFERENCE_OBJ_P(zv) (php_readpreference_fetch_object(Z_OBJ_P(zv)))
120123
# define Z_SERVER_OBJ_P(zv) (php_server_fetch_object(Z_OBJ_P(zv)))
124+
# define Z_SESSION_OBJ_P(zv) (php_session_fetch_object(Z_OBJ_P(zv)))
121125
# define Z_BULKWRITE_OBJ_P(zv) (php_bulkwrite_fetch_object(Z_OBJ_P(zv)))
122126
# define Z_WRITECONCERN_OBJ_P(zv) (php_writeconcern_fetch_object(Z_OBJ_P(zv)))
123127
# define Z_WRITECONCERNERROR_OBJ_P(zv) (php_writeconcernerror_fetch_object(Z_OBJ_P(zv)))
@@ -147,6 +151,7 @@ static inline php_phongo_commandsucceededevent_t* php_commandsucceededevent_fetc
147151
# define Z_OBJ_READCONCERN(zo) (php_readconcern_fetch_object(zo))
148152
# define Z_OBJ_READPREFERENCE(zo) (php_readpreference_fetch_object(zo))
149153
# define Z_OBJ_SERVER(zo) (php_server_fetch_object(zo))
154+
# define Z_OBJ_SESSION(zo) (php_session_fetch_object(zo))
150155
# define Z_OBJ_BULKWRITE(zo) (php_bulkwrite_fetch_object(zo))
151156
# define Z_OBJ_WRITECONCERN(zo) (php_writeconcern_fetch_object(zo))
152157
# define Z_OBJ_WRITECONCERNERROR(zo) (php_writeconcernerror_fetch_object(zo))
@@ -178,6 +183,7 @@ static inline php_phongo_commandsucceededevent_t* php_commandsucceededevent_fetc
178183
# define Z_READCONCERN_OBJ_P(zv) ((php_phongo_readconcern_t *)zend_object_store_get_object(zv TSRMLS_CC))
179184
# define Z_READPREFERENCE_OBJ_P(zv) ((php_phongo_readpreference_t *)zend_object_store_get_object(zv TSRMLS_CC))
180185
# define Z_SERVER_OBJ_P(zv) ((php_phongo_server_t *)zend_object_store_get_object(zv TSRMLS_CC))
186+
# define Z_SESSION_OBJ_P(zv) ((php_phongo_session_t *)zend_object_store_get_object(zv TSRMLS_CC))
181187
# define Z_BULKWRITE_OBJ_P(zv) ((php_phongo_bulkwrite_t *)zend_object_store_get_object(zv TSRMLS_CC))
182188
# define Z_WRITECONCERN_OBJ_P(zv) ((php_phongo_writeconcern_t *)zend_object_store_get_object(zv TSRMLS_CC))
183189
# define Z_WRITECONCERNERROR_OBJ_P(zv) ((php_phongo_writeconcernerror_t *)zend_object_store_get_object(zv TSRMLS_CC))
@@ -207,6 +213,7 @@ static inline php_phongo_commandsucceededevent_t* php_commandsucceededevent_fetc
207213
# define Z_OBJ_READCONCERN(zo) ((php_phongo_readconcern_t *)zo)
208214
# define Z_OBJ_READPREFERENCE(zo) ((php_phongo_readpreference_t *)zo)
209215
# define Z_OBJ_SERVER(zo) ((php_phongo_server_t *)zo)
216+
# define Z_OBJ_SESSION(zo) ((php_phongo_session_t *)zo)
210217
# define Z_OBJ_BULKWRITE(zo) ((php_phongo_bulkwrite_t *)zo)
211218
# define Z_OBJ_WRITECONCERN(zo) ((php_phongo_writeconcern_t *)zo)
212219
# define Z_OBJ_WRITECONCERNERROR(zo) ((php_phongo_writeconcernerror_t *)zo)
@@ -244,6 +251,7 @@ extern zend_class_entry *php_phongo_query_ce;
244251
extern zend_class_entry *php_phongo_readconcern_ce;
245252
extern zend_class_entry *php_phongo_readpreference_ce;
246253
extern zend_class_entry *php_phongo_server_ce;
254+
extern zend_class_entry *php_phongo_session_ce;
247255
extern zend_class_entry *php_phongo_bulkwrite_ce;
248256
extern zend_class_entry *php_phongo_writeconcern_ce;
249257
extern zend_class_entry *php_phongo_writeconcernerror_ce;
@@ -332,6 +340,7 @@ extern void php_phongo_query_init_ce(INIT_FUNC_ARGS);
332340
extern void php_phongo_readconcern_init_ce(INIT_FUNC_ARGS);
333341
extern void php_phongo_readpreference_init_ce(INIT_FUNC_ARGS);
334342
extern void php_phongo_server_init_ce(INIT_FUNC_ARGS);
343+
extern void php_phongo_session_init_ce(INIT_FUNC_ARGS);
335344
extern void php_phongo_writeconcern_init_ce(INIT_FUNC_ARGS);
336345
extern void php_phongo_writeconcernerror_init_ce(INIT_FUNC_ARGS);
337346
extern void php_phongo_writeerror_init_ce(INIT_FUNC_ARGS);

php_phongo_structs.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,12 @@ typedef struct {
106106
PHONGO_ZEND_OBJECT_POST
107107
} php_phongo_server_t;
108108

109+
typedef struct {
110+
PHONGO_ZEND_OBJECT_PRE
111+
mongoc_client_session_t *client_session;
112+
PHONGO_ZEND_OBJECT_POST
113+
} php_phongo_session_t;
114+
109115
typedef struct {
110116
PHONGO_ZEND_OBJECT_PRE
111117
mongoc_write_concern_t *write_concern;

src/MongoDB/Manager.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,42 @@ static PHP_METHOD(Manager, selectServer)
538538
}
539539
} /* }}} */
540540

541+
/* {{{ proto MongoDB\Driver\Session MongoDB\Driver\Manager::startSession([array $options = null])
542+
Returns a new client session */
543+
static PHP_METHOD(Manager, startSession)
544+
{
545+
php_phongo_manager_t *intern;
546+
zval *options = NULL;
547+
mongoc_session_opt_t *cs_opts = NULL;
548+
mongoc_client_session_t *cs;
549+
bson_error_t error;
550+
SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used)
551+
552+
553+
intern = Z_MANAGER_OBJ_P(getThis());
554+
555+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!", &options) == FAILURE) {
556+
return;
557+
}
558+
559+
if (options && php_array_exists(options, "causalConsistency")) {
560+
cs_opts = mongoc_session_opts_new();
561+
mongoc_session_opts_set_causal_consistency(cs_opts, php_array_fetchc_bool(options, "causalConsistency"));
562+
}
563+
564+
cs = mongoc_client_start_session(intern->client, cs_opts, &error);
565+
566+
if (cs_opts) {
567+
mongoc_session_opts_destroy(cs_opts);
568+
}
569+
570+
if (cs) {
571+
phongo_session_init(return_value, cs TSRMLS_CC);
572+
} else {
573+
phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC);
574+
}
575+
} /* }}} */
576+
541577
/* {{{ MongoDB\Driver\Manager function entries */
542578
ZEND_BEGIN_ARG_INFO_EX(ai_Manager___construct, 0, 0, 0)
543579
ZEND_ARG_INFO(0, uri)
@@ -573,6 +609,10 @@ ZEND_BEGIN_ARG_INFO_EX(ai_Manager_selectServer, 0, 0, 1)
573609
ZEND_ARG_OBJ_INFO(0, readPreference, MongoDB\\Driver\\ReadPreference, 1)
574610
ZEND_END_ARG_INFO()
575611

612+
ZEND_BEGIN_ARG_INFO_EX(ai_Manager_startSession, 0, 0, 0)
613+
ZEND_ARG_ARRAY_INFO(0, options, 1)
614+
ZEND_END_ARG_INFO()
615+
576616
ZEND_BEGIN_ARG_INFO_EX(ai_Manager_void, 0, 0, 0)
577617
ZEND_END_ARG_INFO()
578618

@@ -589,6 +629,7 @@ static zend_function_entry php_phongo_manager_me[] = {
589629
PHP_ME(Manager, getServers, ai_Manager_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
590630
PHP_ME(Manager, getWriteConcern, ai_Manager_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
591631
PHP_ME(Manager, selectServer, ai_Manager_selectServer, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
632+
PHP_ME(Manager, startSession, ai_Manager_startSession, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
592633
ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_Manager_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
593634
PHP_FE_END
594635
};

0 commit comments

Comments
 (0)