2929/* External libs */
3030#include <bson.h>
3131#include <mongoc.h>
32+ #include <mongoc-cursor-cursorid-private.h>
3233
3334
3435/* PHP Core stuff */
@@ -221,7 +222,7 @@ void phongo_log_writer(mongoc_stream_t *stream, int32_t timeout_msec, ssize_t se
221222/* }}} */
222223
223224/* {{{ Init objects */
224- void phongo_result_init (zval * return_value , zend_class_entry * result_class , mongoc_cursor_t * cursor , const bson_t * bson , int server_hint TSRMLS_DC ) /* {{{ */
225+ void phongo_result_init (zval * return_value , zend_class_entry * result_class , mongoc_cursor_t * cursor , const bson_t * bson , int server_hint , zend_bool is_command_cursor TSRMLS_DC ) /* {{{ */
225226{
226227 php_phongo_result_t * result ;
227228
@@ -234,6 +235,7 @@ void phongo_result_init(zval *return_value, zend_class_entry *result_class, mong
234235 } else {
235236 result -> hint = server_hint ;
236237 }
238+ result -> is_command_cursor = is_command_cursor ;
237239 result -> firstBatch = bson ? bson_copy (bson ) : NULL ;
238240} /* }}} */
239241
@@ -310,7 +312,7 @@ void phongo_writeresult_init(zval *return_value, const bson_t *bson, int server_
310312 bson_iter_t iter , ar ;
311313 php_phongo_writeresult_t * writeresult ;
312314
313- phongo_result_init (return_value , php_phongo_writeresult_ce , NULL , bson , server_hint TSRMLS_CC );
315+ phongo_result_init (return_value , php_phongo_writeresult_ce , NULL , bson , server_hint , 0 TSRMLS_CC );
314316 writeresult = (php_phongo_writeresult_t * )zend_object_store_get_object (return_value TSRMLS_CC );
315317
316318 if (bson_iter_init_find (& iter , bson , "nUpserted" ) && BSON_ITER_HOLDS_INT32 (& iter )) {
@@ -622,14 +624,16 @@ int phongo_execute_query(mongoc_client_t *client, char *namespace, php_phongo_qu
622624 return true;
623625 }
624626
625- phongo_result_init (return_value , php_phongo_queryresult_ce , cursor , doc , 0 TSRMLS_CC );
627+ phongo_result_init (return_value , php_phongo_queryresult_ce , cursor , doc , 0 , 0 TSRMLS_CC );
626628 return true;
627629} /* }}} */
628630
629631int phongo_execute_command (mongoc_client_t * client , char * db , bson_t * command , mongoc_read_prefs_t * read_preference , zval * return_value , int return_value_used TSRMLS_DC ) /* {{{ */
630632{
631633 mongoc_cursor_t * cursor ;
632634 const bson_t * doc ;
635+ bson_iter_t iter ;
636+ bson_iter_t child ;
633637
634638
635639 cursor = mongoc_client_command (client , db , MONGOC_QUERY_NONE , 0 , 1 , 0 , command , NULL , read_preference );
@@ -649,7 +653,28 @@ int phongo_execute_command(mongoc_client_t *client, char *db, bson_t *command, m
649653 return true;
650654 }
651655
652- phongo_result_init (return_value , php_phongo_commandresult_ce , cursor , doc , 0 TSRMLS_CC );
656+ /* Detect if its an command cursor */
657+ if (bson_iter_init_find (& iter , doc , "cursor" ) && BSON_ITER_HOLDS_DOCUMENT (& iter ) && bson_iter_recurse (& iter , & child )) {
658+ while (bson_iter_next (& child )) {
659+ if (BSON_ITER_IS_KEY (& child , "firstBatch" )) {
660+ if (BSON_ITER_HOLDS_ARRAY (& child )) {
661+ const uint8_t * data = NULL ;
662+ uint32_t data_len = 0 ;
663+ bson_t first_batch ;
664+
665+ bson_iter_array (& child , & data_len , & data );
666+ if (bson_init_static (& first_batch , data , data_len )) {
667+ _phongo_debug_bson (& first_batch );
668+ _mongoc_cursor_cursorid_init (cursor );
669+ phongo_result_init (return_value , php_phongo_commandresult_ce , cursor , & first_batch , mongoc_cursor_get_hint (cursor ), 1 TSRMLS_CC );
670+ return true;
671+ }
672+ }
673+ }
674+ }
675+ }
676+
677+ phongo_result_init (return_value , php_phongo_commandresult_ce , cursor , doc , mongoc_cursor_get_hint (cursor ), 0 TSRMLS_CC );
653678 return true;
654679} /* }}} */
655680
@@ -999,6 +1024,7 @@ void php_phongo_cursor_new_from_result(zval *object, php_phongo_result_t *result
9991024
10001025 intern = (php_phongo_cursor_t * )zend_object_store_get_object (object TSRMLS_CC );
10011026 intern -> cursor = result -> cursor ;
1027+ intern -> is_command_cursor = result -> is_command_cursor ;
10021028 intern -> firstBatch = result -> firstBatch ;
10031029 intern -> hint = result -> hint ;
10041030} /* }}} */
@@ -1110,9 +1136,11 @@ void php_phongo_result_free(php_phongo_result_t *result)
11101136typedef struct {
11111137 zend_object_iterator iterator ;
11121138 zval * current ;
1113- mongoc_cursor_t * cursor ;
1114- bson_t * firstBatch ;
1115- int hint ;
1139+ mongoc_cursor_t * cursor ;
1140+ bson_t * firstBatch ;
1141+ bson_iter_t first_batch_iter ;
1142+ int hint ;
1143+ zend_bool is_command_cursor ;
11161144} phongo_cursor_it ;
11171145
11181146static void phongo_cursor_it_dtor (zend_object_iterator * iter TSRMLS_DC ) /* {{{ */
@@ -1147,6 +1175,17 @@ static void phongo_cursor_it_move_forward(zend_object_iterator *iter TSRMLS_DC)
11471175 cursor_it -> current = NULL ;
11481176 }
11491177
1178+ if (bson_iter_next (& cursor_it -> first_batch_iter )) {
1179+ if (BSON_ITER_HOLDS_DOCUMENT (& cursor_it -> first_batch_iter )) {
1180+ const uint8_t * data = NULL ;
1181+ uint32_t data_len = 0 ;
1182+
1183+ bson_iter_document (& cursor_it -> first_batch_iter , & data_len , & data );
1184+ MAKE_STD_ZVAL (cursor_it -> current );
1185+ bson_to_zval (data , data_len , cursor_it -> current );
1186+ return ;
1187+ }
1188+ }
11501189 if (mongoc_cursor_next (cursor_it -> cursor , & doc )) {
11511190 MAKE_STD_ZVAL (cursor_it -> current );
11521191 bson_to_zval (bson_get_data (doc ), doc -> len , cursor_it -> current );
@@ -1162,8 +1201,22 @@ static void phongo_cursor_it_rewind(zend_object_iterator *iter TSRMLS_DC) /* {{{
11621201
11631202 /* firstBatch is empty when the query simply didn't return any results */
11641203 if (cursor_it -> firstBatch ) {
1165- MAKE_STD_ZVAL (cursor_it -> current );
1166- bson_to_zval (bson_get_data (cursor_it -> firstBatch ), cursor_it -> firstBatch -> len , cursor_it -> current );
1204+ if (cursor_it -> is_command_cursor ) {
1205+ bson_iter_init (& cursor_it -> first_batch_iter , cursor_it -> firstBatch );
1206+ if (bson_iter_next (& cursor_it -> first_batch_iter )) {
1207+ if (BSON_ITER_HOLDS_DOCUMENT (& cursor_it -> first_batch_iter )) {
1208+ const uint8_t * data = NULL ;
1209+ uint32_t data_len = 0 ;
1210+
1211+ bson_iter_document (& cursor_it -> first_batch_iter , & data_len , & data );
1212+ MAKE_STD_ZVAL (cursor_it -> current );
1213+ bson_to_zval (data , data_len , cursor_it -> current );
1214+ }
1215+ }
1216+ } else {
1217+ MAKE_STD_ZVAL (cursor_it -> current );
1218+ bson_to_zval (bson_get_data (cursor_it -> firstBatch ), cursor_it -> firstBatch -> len , cursor_it -> current );
1219+ }
11671220 }
11681221} /* }}} */
11691222
@@ -1200,11 +1253,12 @@ zend_object_iterator *phongo_cursor_get_iterator(zend_class_entry *ce, zval *obj
12001253 cursor_it = ecalloc (1 , sizeof (phongo_cursor_it ));
12011254
12021255 Z_ADDREF_P (object );
1203- cursor_it -> iterator .data = (void * )object ;
1256+ cursor_it -> iterator .data = (void * )object ;
12041257 cursor_it -> iterator .funcs = & phongo_cursor_it_funcs ;
1205- cursor_it -> cursor = intern -> cursor ;
1206- cursor_it -> firstBatch = intern -> firstBatch ;
1207- cursor_it -> hint = intern -> hint ;
1258+ cursor_it -> cursor = intern -> cursor ;
1259+ cursor_it -> is_command_cursor = intern -> is_command_cursor ;
1260+ cursor_it -> firstBatch = intern -> firstBatch ;
1261+ cursor_it -> hint = intern -> hint ;
12081262
12091263 return (zend_object_iterator * )cursor_it ;
12101264} /* }}} */
@@ -1237,11 +1291,12 @@ zend_object_iterator *phongo_result_get_iterator(zend_class_entry *ce, zval *obj
12371291 cursor_it = ecalloc (1 , sizeof (phongo_cursor_it ));
12381292
12391293 Z_ADDREF_P (object );
1240- cursor_it -> iterator .data = (void * )object ;
1294+ cursor_it -> iterator .data = (void * )object ;
12411295 cursor_it -> iterator .funcs = & phongo_cursor_it_funcs ;
1242- cursor_it -> cursor = intern -> cursor ;
1243- cursor_it -> firstBatch = intern -> firstBatch ;
1244- cursor_it -> hint = intern -> hint ;
1296+ cursor_it -> cursor = intern -> cursor ;
1297+ cursor_it -> firstBatch = intern -> firstBatch ;
1298+ cursor_it -> hint = intern -> hint ;
1299+ cursor_it -> is_command_cursor = intern -> is_command_cursor ;
12451300
12461301 return (zend_object_iterator * )cursor_it ;
12471302 }
@@ -1273,6 +1328,17 @@ static void php_phongo_free(void *mem) /* {{{ */
12731328
12741329/* }}} */
12751330
1331+ #ifdef PHP_DEBUG
1332+ void _phongo_debug_bson (bson_t * bson )
1333+ {
1334+ char * str ;
1335+ size_t str_len ;
1336+
1337+ str = bson_as_json (bson , & str_len );
1338+
1339+ php_printf ("JSON: %s\n" , str );
1340+ }
1341+ #endif
12761342
12771343/* {{{ M[INIT|SHUTDOWN] R[INIT|SHUTDOWN] G[INIT|SHUTDOWN] MINFO INI */
12781344
0 commit comments