@@ -749,7 +749,7 @@ bool phongo_cursor_advance_and_check_for_error(mongoc_cursor_t *cursor TSRMLS_DC
749
749
return true;
750
750
} /* }}} */
751
751
752
- int phongo_execute_query (mongoc_client_t * client , const char * namespace , zval * zquery , zval * options , uint32_t server_id , zval * return_value , int return_value_used TSRMLS_DC ) /* {{{ */
752
+ bool phongo_execute_query (mongoc_client_t * client , const char * namespace , zval * zquery , zval * options , uint32_t server_id , zval * return_value , int return_value_used TSRMLS_DC ) /* {{{ */
753
753
{
754
754
const php_phongo_query_t * query ;
755
755
mongoc_cursor_t * cursor ;
@@ -827,7 +827,29 @@ static bson_t *create_wrapped_command_envelope(const char *db, bson_t *reply)
827
827
return tmp ;
828
828
}
829
829
830
- int phongo_execute_command (mongoc_client_t * client , php_phongo_command_type_t type , const char * db , zval * zcommand , zval * options , uint32_t server_id , zval * return_value , int return_value_used TSRMLS_DC ) /* {{{ */
830
+ static zval * phongo_create_implicit_session (mongoc_client_t * client TSRMLS_DC ) /* {{{ */
831
+ {
832
+ mongoc_client_session_t * cs ;
833
+ zval * zsession ;
834
+
835
+ cs = mongoc_client_start_session (client , NULL , NULL );
836
+
837
+ if (!cs ) {
838
+ return NULL ;
839
+ }
840
+
841
+ #if PHP_VERSION_ID >= 70000
842
+ zsession = ecalloc (sizeof (zval ), 1 );
843
+ #else
844
+ ALLOC_INIT_ZVAL (zsession );
845
+ #endif
846
+
847
+ phongo_session_init (zsession , cs TSRMLS_CC );
848
+
849
+ return zsession ;
850
+ } /* }}} */
851
+
852
+ bool phongo_execute_command (mongoc_client_t * client , php_phongo_command_type_t type , const char * db , zval * zcommand , zval * options , uint32_t server_id , zval * return_value , int return_value_used TSRMLS_DC ) /* {{{ */
831
853
{
832
854
const php_phongo_command_t * command ;
833
855
bson_iter_t iter ;
@@ -837,38 +859,50 @@ int phongo_execute_command(mongoc_client_t *client, php_phongo_command_type_t ty
837
859
mongoc_cursor_t * cmd_cursor ;
838
860
zval * zreadPreference = NULL ;
839
861
zval * zsession = NULL ;
840
- int result ;
862
+ bool result = false;
863
+ bool free_reply = false;
864
+ bool free_zsession = false;
841
865
842
866
command = Z_COMMAND_OBJ_P (zcommand );
843
867
844
868
if ((type & PHONGO_OPTION_READ_CONCERN ) && !phongo_parse_read_concern (options , & opts TSRMLS_CC )) {
845
869
/* Exception should already have been thrown */
846
- bson_destroy (& opts );
847
- return false;
870
+ goto cleanup ;
848
871
}
849
872
850
873
if ((type & PHONGO_OPTION_READ_PREFERENCE ) && !phongo_parse_read_preference (options , & zreadPreference TSRMLS_CC )) {
851
874
/* Exception should already have been thrown */
852
- bson_destroy (& opts );
853
- return false;
875
+ goto cleanup ;
854
876
}
855
877
856
878
if (!phongo_parse_session (options , client , & opts , & zsession TSRMLS_CC )) {
857
879
/* Exception should already have been thrown */
858
- bson_destroy (& opts );
859
- return false;
880
+ goto cleanup ;
881
+ }
882
+
883
+ /* If an explicit session was not provided, attempt to create an implicit
884
+ * client session (ignoring any errors). */
885
+ if (!zsession ) {
886
+ zsession = phongo_create_implicit_session (client TSRMLS_CC );
887
+
888
+ if (zsession ) {
889
+ free_zsession = true;
890
+
891
+ if (!mongoc_client_session_append (Z_SESSION_OBJ_P (zsession )-> client_session , & opts , NULL )) {
892
+ phongo_throw_exception (PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC , "Error appending implicit \"sessionId\" option" );
893
+ goto cleanup ;
894
+ }
895
+ }
860
896
}
861
897
862
898
if ((type & PHONGO_OPTION_WRITE_CONCERN ) && !phongo_parse_write_concern (options , & opts , NULL TSRMLS_CC )) {
863
899
/* Exception should already have been thrown */
864
- bson_destroy (& opts );
865
- return false;
900
+ goto cleanup ;
866
901
}
867
902
868
903
if (!BSON_APPEND_INT32 (& opts , "serverId" , server_id )) {
869
904
phongo_throw_exception (PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC , "Error appending \"serverId\" option" );
870
- bson_destroy (& opts );
871
- return false;
905
+ goto cleanup ;
872
906
}
873
907
874
908
/* Although "opts" already always includes the serverId option, the read
@@ -891,27 +925,25 @@ int phongo_execute_command(mongoc_client_t *client, php_phongo_command_type_t ty
891
925
default :
892
926
/* Should never happen, but if it does: exception */
893
927
phongo_throw_exception (PHONGO_ERROR_LOGIC TSRMLS_CC , "Type '%d' should never have been passed to phongo_execute_command, please file a bug report" , type );
894
- bson_destroy (& opts );
895
- return false;
928
+ goto cleanup ;
896
929
}
930
+
931
+ free_reply = true;
932
+
897
933
if (!result ) {
898
934
phongo_throw_exception_from_bson_error_t (& error TSRMLS_CC );
899
- bson_destroy (& reply );
900
- bson_destroy (& opts );
901
- return false;
935
+ goto cleanup ;
902
936
}
903
937
904
- bson_destroy (& opts );
905
-
906
938
if (!return_value_used ) {
907
- bson_destroy (& reply );
908
- return true;
939
+ goto cleanup ;
909
940
}
910
941
911
942
/* According to mongoc_cursor_new_from_command_reply(), the reply bson_t
912
943
* is ultimately destroyed on both success and failure. */
913
944
if (bson_iter_init_find (& iter , & reply , "cursor" ) && BSON_ITER_HOLDS_DOCUMENT (& iter )) {
914
945
bson_t initial_reply = BSON_INITIALIZER ;
946
+ bson_error_t error = {0 };
915
947
916
948
bson_copy_to (& reply , & initial_reply );
917
949
@@ -925,17 +957,39 @@ int phongo_execute_command(mongoc_client_t *client, php_phongo_command_type_t ty
925
957
bson_append_int64 (& initial_reply , "batchSize" , -1 , command -> batch_size );
926
958
}
927
959
960
+ if (zsession && !mongoc_client_session_append (Z_SESSION_OBJ_P (zsession )-> client_session , & initial_reply , & error )) {
961
+ phongo_throw_exception_from_bson_error_t (& error TSRMLS_CC );
962
+ bson_destroy (& initial_reply );
963
+ result = false;
964
+ goto cleanup ;
965
+ }
966
+
928
967
cmd_cursor = mongoc_cursor_new_from_command_reply (client , & initial_reply , server_id );
929
- bson_destroy (& reply );
930
968
} else {
931
969
bson_t * wrapped_reply = create_wrapped_command_envelope (db , & reply );
932
970
933
971
cmd_cursor = mongoc_cursor_new_from_command_reply (client , wrapped_reply , server_id );
934
- bson_destroy (& reply );
935
972
}
936
973
937
974
phongo_cursor_init_for_command (return_value , client , cmd_cursor , db , zcommand , zreadPreference , zsession TSRMLS_CC );
938
- return true;
975
+
976
+ cleanup :
977
+ bson_destroy (& opts );
978
+
979
+ if (free_reply ) {
980
+ bson_destroy (& reply );
981
+ }
982
+
983
+ if (free_zsession ) {
984
+ #if PHP_VERSION_ID >= 70000
985
+ zval_ptr_dtor (zsession );
986
+ efree (zsession );
987
+ #else
988
+ zval_ptr_dtor (& zsession );
989
+ #endif
990
+ }
991
+
992
+ return result ;
939
993
} /* }}} */
940
994
/* }}} */
941
995
0 commit comments