29
29
/* External libs */
30
30
#include <bson.h>
31
31
#include <mongoc.h>
32
+ #include <mongoc-cursor-cursorid-private.h>
32
33
33
34
34
35
/* PHP Core stuff */
@@ -221,7 +222,7 @@ void phongo_log_writer(mongoc_stream_t *stream, int32_t timeout_msec, ssize_t se
221
222
/* }}} */
222
223
223
224
/* {{{ 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 ) /* {{{ */
225
226
{
226
227
php_phongo_result_t * result ;
227
228
@@ -234,6 +235,7 @@ void phongo_result_init(zval *return_value, zend_class_entry *result_class, mong
234
235
} else {
235
236
result -> hint = server_hint ;
236
237
}
238
+ result -> is_command_cursor = is_command_cursor ;
237
239
result -> firstBatch = bson ? bson_copy (bson ) : NULL ;
238
240
} /* }}} */
239
241
@@ -310,7 +312,7 @@ void phongo_writeresult_init(zval *return_value, const bson_t *bson, int server_
310
312
bson_iter_t iter , ar ;
311
313
php_phongo_writeresult_t * writeresult ;
312
314
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 );
314
316
writeresult = (php_phongo_writeresult_t * )zend_object_store_get_object (return_value TSRMLS_CC );
315
317
316
318
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
622
624
return true;
623
625
}
624
626
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 );
626
628
return true;
627
629
} /* }}} */
628
630
629
631
int 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 ) /* {{{ */
630
632
{
631
633
mongoc_cursor_t * cursor ;
632
634
const bson_t * doc ;
635
+ bson_iter_t iter ;
636
+ bson_iter_t child ;
633
637
634
638
635
639
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
649
653
return true;
650
654
}
651
655
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 );
653
678
return true;
654
679
} /* }}} */
655
680
@@ -999,6 +1024,7 @@ void php_phongo_cursor_new_from_result(zval *object, php_phongo_result_t *result
999
1024
1000
1025
intern = (php_phongo_cursor_t * )zend_object_store_get_object (object TSRMLS_CC );
1001
1026
intern -> cursor = result -> cursor ;
1027
+ intern -> is_command_cursor = result -> is_command_cursor ;
1002
1028
intern -> firstBatch = result -> firstBatch ;
1003
1029
intern -> hint = result -> hint ;
1004
1030
} /* }}} */
@@ -1110,9 +1136,11 @@ void php_phongo_result_free(php_phongo_result_t *result)
1110
1136
typedef struct {
1111
1137
zend_object_iterator iterator ;
1112
1138
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 ;
1116
1144
} phongo_cursor_it ;
1117
1145
1118
1146
static 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)
1147
1175
cursor_it -> current = NULL ;
1148
1176
}
1149
1177
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
+ }
1150
1189
if (mongoc_cursor_next (cursor_it -> cursor , & doc )) {
1151
1190
MAKE_STD_ZVAL (cursor_it -> current );
1152
1191
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) /* {{{
1162
1201
1163
1202
/* firstBatch is empty when the query simply didn't return any results */
1164
1203
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
+ }
1167
1220
}
1168
1221
} /* }}} */
1169
1222
@@ -1200,11 +1253,12 @@ zend_object_iterator *phongo_cursor_get_iterator(zend_class_entry *ce, zval *obj
1200
1253
cursor_it = ecalloc (1 , sizeof (phongo_cursor_it ));
1201
1254
1202
1255
Z_ADDREF_P (object );
1203
- cursor_it -> iterator .data = (void * )object ;
1256
+ cursor_it -> iterator .data = (void * )object ;
1204
1257
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 ;
1208
1262
1209
1263
return (zend_object_iterator * )cursor_it ;
1210
1264
} /* }}} */
@@ -1237,11 +1291,12 @@ zend_object_iterator *phongo_result_get_iterator(zend_class_entry *ce, zval *obj
1237
1291
cursor_it = ecalloc (1 , sizeof (phongo_cursor_it ));
1238
1292
1239
1293
Z_ADDREF_P (object );
1240
- cursor_it -> iterator .data = (void * )object ;
1294
+ cursor_it -> iterator .data = (void * )object ;
1241
1295
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 ;
1245
1300
1246
1301
return (zend_object_iterator * )cursor_it ;
1247
1302
}
@@ -1273,6 +1328,17 @@ static void php_phongo_free(void *mem) /* {{{ */
1273
1328
1274
1329
/* }}} */
1275
1330
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
1276
1342
1277
1343
/* {{{ M[INIT|SHUTDOWN] R[INIT|SHUTDOWN] G[INIT|SHUTDOWN] MINFO INI */
1278
1344
0 commit comments