@@ -235,7 +235,7 @@ static void php_phongo_log(mongoc_log_level_t log_level, const char *log_domain,
235235/* }}} */
236236
237237/* {{{ Init objects */
238- void phongo_cursor_init (zval * return_value , mongoc_cursor_t * cursor , const bson_t * bson , mongoc_client_t * client , zend_bool is_command_cursor TSRMLS_DC ) /* {{{ */
238+ void phongo_cursor_init (zval * return_value , mongoc_cursor_t * cursor , mongoc_client_t * client TSRMLS_DC ) /* {{{ */
239239{
240240 php_phongo_cursor_t * intern ;
241241
@@ -245,8 +245,6 @@ void phongo_cursor_init(zval *return_value, mongoc_cursor_t *cursor, const bson_
245245 intern -> cursor = cursor ;
246246 intern -> server_id = mongoc_cursor_get_hint (cursor );
247247 intern -> client = client ;
248- intern -> is_command_cursor = is_command_cursor ;
249- intern -> firstBatch = bson ? bson_copy (bson ) : NULL ;
250248} /* }}} */
251249
252250void phongo_server_init (zval * return_value , mongoc_client_t * client , int server_id TSRMLS_DC ) /* {{{ */
@@ -589,7 +587,7 @@ int phongo_execute_query(mongoc_client_t *client, const char *namespace, const p
589587 return true;
590588 }
591589
592- phongo_cursor_init (return_value , cursor , doc , client , 0 TSRMLS_CC );
590+ phongo_cursor_init (return_value , cursor , client TSRMLS_CC );
593591 return true;
594592} /* }}} */
595593
@@ -619,36 +617,43 @@ int phongo_execute_command(mongoc_client_t *client, const char *db, const bson_t
619617 return true;
620618 }
621619
622- /* Detect if its an command cursor */
623- if (bson_iter_init_find (& iter , doc , "cursor" ) && BSON_ITER_HOLDS_DOCUMENT (& iter ) && bson_iter_recurse (& iter , & child )) {
624- while (bson_iter_next (& child )) {
625- if (BSON_ITER_IS_KEY (& child , "id" )) {
626- cursor -> rpc .reply .cursor_id = bson_iter_as_int64 (& child );
627- } else if (BSON_ITER_IS_KEY (& child , "ns" )) {
620+ /* This code is adapated from _mongoc_cursor_cursorid_prime(), but we avoid
621+ * advancing the cursor, since we are already positioned at the first result
622+ * after the error checking above. */
623+ if (bson_iter_init_find (& iter , doc , "cursor" ) && BSON_ITER_HOLDS_DOCUMENT (& iter ) && bson_iter_recurse (& iter , & child )) {
624+ mongoc_cursor_cursorid_t * cid ;
625+
626+ _mongoc_cursor_cursorid_init (cursor );
627+ cursor -> limit = 0 ;
628+
629+ cid = cursor -> iface_data ;
630+ cid -> has_cursor = true;
631+
632+ while (bson_iter_next (& child )) {
633+ if (BSON_ITER_IS_KEY (& child , "id" )) {
634+ cursor -> rpc .reply .cursor_id = bson_iter_as_int64 (& child );
635+ } else if (BSON_ITER_IS_KEY (& child , "ns" )) {
628636 const char * ns ;
629637
630- ns = bson_iter_utf8 (& child , & cursor -> nslen );
631- bson_strncpy (cursor -> ns , ns , sizeof cursor -> ns );
632- } else if (BSON_ITER_IS_KEY (& child , "firstBatch" )) {
633- if (BSON_ITER_HOLDS_ARRAY (& child )) {
634- const uint8_t * data = NULL ;
635- uint32_t data_len = 0 ;
636- bson_t first_batch ;
637-
638- bson_iter_array (& child , & data_len , & data );
639- if (bson_init_static (& first_batch , data , data_len )) {
640- _mongoc_cursor_cursorid_init (cursor );
641- cursor -> limit = 0 ;
642- cursor -> is_command = false;
643- phongo_cursor_init (return_value , cursor , & first_batch , client , 1 TSRMLS_CC );
644- return true;
645- }
638+ ns = bson_iter_utf8 (& child , & cursor -> nslen );
639+ bson_strncpy (cursor -> ns , ns , sizeof cursor -> ns );
640+ } else if (BSON_ITER_IS_KEY (& child , "firstBatch" )) {
641+ if (BSON_ITER_HOLDS_ARRAY (& child ) && bson_iter_recurse (& child , & cid -> first_batch_iter )) {
642+ cid -> in_first_batch = true;
646643 }
647644 }
648645 }
646+
647+ cursor -> is_command = false;
648+
649+ /* The cursor's current element is the command's response document.
650+ * Advance once so that the cursor is positioned at the first document
651+ * within the command cursor's result set.
652+ */
653+ mongoc_cursor_next (cursor , & doc );
649654 }
650655
651- phongo_cursor_init (return_value , cursor , doc , client , 0 TSRMLS_CC );
656+ phongo_cursor_init (return_value , cursor , client TSRMLS_CC );
652657 return true;
653658} /* }}} */
654659
@@ -1291,17 +1296,7 @@ void php_phongo_cursor_to_zval(zval *retval, php_phongo_cursor_t *cursor) /* {{{
12911296 add_assoc_null_ex (retval , ZEND_STRS ("cursor" ));
12921297 }
12931298
1294- if (cursor -> firstBatch ) {
1295- php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER ;
1296-
1297- MAKE_STD_ZVAL (state .zchild );
1298- bson_to_zval (bson_get_data (cursor -> firstBatch ), cursor -> firstBatch -> len , & state );
1299- add_assoc_zval_ex (retval , ZEND_STRS ("firstBatch" ), state .zchild );
1300- } else {
1301- add_assoc_null_ex (retval , ZEND_STRS ("firstBatch" ));
1302- }
13031299 add_assoc_long_ex (retval , ZEND_STRS ("server_id" ), cursor -> server_id );
1304- add_assoc_bool_ex (retval , ZEND_STRS ("is_command_cursor" ), cursor -> is_command_cursor );
13051300
13061301} /* }}} */
13071302
@@ -1560,14 +1555,11 @@ static void php_phongo_cursor_free_current(php_phongo_cursor_t *cursor) /* {{{ *
15601555
15611556void php_phongo_cursor_free (php_phongo_cursor_t * cursor )
15621557{
1563- if (cursor -> firstBatch ) {
1564- bson_clear (& cursor -> firstBatch );
1565- cursor -> firstBatch = NULL ;
1566- }
15671558 if (cursor -> cursor ) {
15681559 mongoc_cursor_destroy (cursor -> cursor );
15691560 cursor -> cursor = NULL ;
15701561 }
1562+
15711563 php_phongo_cursor_free_current (cursor );
15721564}
15731565
@@ -1576,13 +1568,6 @@ static void php_phongo_cursor_iterator_dtor(zend_object_iterator *iter TSRMLS_DC
15761568{
15771569 php_phongo_cursor_iterator * cursor_it = (php_phongo_cursor_iterator * )iter ;
15781570
1579- if (cursor_it -> cursor -> firstBatch ) {
1580- bson_clear (& cursor_it -> cursor -> firstBatch );
1581- cursor_it -> cursor -> firstBatch = NULL ;
1582- }
1583-
1584- php_phongo_cursor_free_current (cursor_it -> cursor );
1585-
15861571 if (cursor_it -> intern .data ) {
15871572 zval_ptr_dtor ((zval * * )& cursor_it -> intern .data );
15881573 cursor_it -> intern .data = NULL ;
@@ -1631,18 +1616,6 @@ static void php_phongo_cursor_iterator_move_forward(zend_object_iterator *iter T
16311616 php_phongo_cursor_free_current (cursor );
16321617 cursor_it -> current ++ ;
16331618
1634- if (bson_iter_next (& cursor_it -> first_batch_iter )) {
1635- if (BSON_ITER_HOLDS_DOCUMENT (& cursor_it -> first_batch_iter )) {
1636- const uint8_t * data = NULL ;
1637- uint32_t data_len = 0 ;
1638-
1639- bson_iter_document (& cursor_it -> first_batch_iter , & data_len , & data );
1640-
1641- MAKE_STD_ZVAL (cursor -> visitor_data .zchild );
1642- bson_to_zval (data , data_len , & cursor -> visitor_data );
1643- return ;
1644- }
1645- }
16461619 if (mongoc_cursor_next (cursor -> cursor , & doc )) {
16471620 MAKE_STD_ZVAL (cursor -> visitor_data .zchild );
16481621 bson_to_zval (bson_get_data (doc ), doc -> len , & cursor -> visitor_data );
@@ -1653,30 +1626,15 @@ static void php_phongo_cursor_iterator_rewind(zend_object_iterator *iter TSRMLS_
16531626{
16541627 php_phongo_cursor_iterator * cursor_it = (php_phongo_cursor_iterator * )iter ;
16551628 php_phongo_cursor_t * cursor = cursor_it -> cursor ;
1629+ const bson_t * doc ;
16561630
16571631 php_phongo_cursor_free_current (cursor );
1658- cursor_it -> current = 0 ;
16591632
1660- /* firstBatch is empty when the query simply didn't return any results */
1661- if (cursor -> firstBatch ) {
1662- if (cursor -> is_command_cursor ) {
1663- if (!bson_iter_init (& cursor_it -> first_batch_iter , cursor -> firstBatch )) {
1664- return ;
1665- }
1666- if (bson_iter_next (& cursor_it -> first_batch_iter )) {
1667- if (BSON_ITER_HOLDS_DOCUMENT (& cursor_it -> first_batch_iter )) {
1668- const uint8_t * data = NULL ;
1669- uint32_t data_len = 0 ;
1670-
1671- bson_iter_document (& cursor_it -> first_batch_iter , & data_len , & data );
1672- MAKE_STD_ZVAL (cursor -> visitor_data .zchild );
1673- bson_to_zval (data , data_len , & cursor -> visitor_data );
1674- }
1675- }
1676- } else {
1677- MAKE_STD_ZVAL (cursor -> visitor_data .zchild );
1678- bson_to_zval (bson_get_data (cursor -> firstBatch ), cursor -> firstBatch -> len , & cursor -> visitor_data );
1679- }
1633+ doc = mongoc_cursor_current (cursor -> cursor );
1634+
1635+ if (doc ) {
1636+ MAKE_STD_ZVAL (cursor -> visitor_data .zchild );
1637+ bson_to_zval (bson_get_data (doc ), doc -> len , & cursor -> visitor_data );
16801638 }
16811639} /* }}} */
16821640
0 commit comments