Skip to content

Commit 1c31f2f

Browse files
committed
PHPC-133: var_dump()ing cursor
1 parent 8c89c1c commit 1c31f2f

File tree

3 files changed

+250
-26
lines changed

3 files changed

+250
-26
lines changed

src/MongoDB/Cursor.c

Lines changed: 160 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <bson.h>
2929
#include <mongoc.h>
3030
#include <mongoc-cursor-private.h>
31+
#include <mongoc-read-prefs-private.h>
3132

3233
/* PHP Core stuff */
3334
#include <php.h>
@@ -45,6 +46,8 @@
4546

4647
PHONGO_API zend_class_entry *php_phongo_cursor_ce;
4748

49+
zend_object_handlers php_phongo_handler_cursor;
50+
4851
/* {{{ proto MongoDB\Driver\Cursor Cursor::__construct(MongoDB\Driver\Server $server, MongoDB\Driver\CursorId $cursorId, array $firstBatch)
4952
Construct a new Cursor */
5053
PHP_METHOD(Cursor, __construct)
@@ -54,6 +57,7 @@ PHP_METHOD(Cursor, __construct)
5457
zval *server;
5558
zval *cursorId;
5659
zval *firstBatch;
60+
(void)return_value; (void)return_value_ptr; (void)return_value_used;
5761

5862

5963
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
@@ -73,6 +77,7 @@ PHP_METHOD(Cursor, getId)
7377
{
7478
php_phongo_cursor_t *intern;
7579
zend_error_handling error_handling;
80+
(void)return_value_ptr; (void)return_value_used;
7681

7782

7883
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
@@ -93,6 +98,7 @@ PHP_METHOD(Cursor, getServer)
9398
{
9499
php_phongo_cursor_t *intern;
95100
zend_error_handling error_handling;
101+
(void)return_value_ptr; (void)return_value_used;
96102

97103

98104
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
@@ -104,6 +110,8 @@ PHP_METHOD(Cursor, getServer)
104110
}
105111
zend_restore_error_handling(&error_handling TSRMLS_CC);
106112

113+
/* FIXME: NOT IMPLEMENTED YET */
114+
RETURN_NULL();
107115
}
108116
/* }}} */
109117
/* {{{ proto boolean Cursor::isDead()
@@ -112,6 +120,7 @@ PHP_METHOD(Cursor, isDead)
112120
{
113121
php_phongo_cursor_t *intern;
114122
zend_error_handling error_handling;
123+
(void)return_value_ptr; (void)return_value_used;
115124

116125

117126
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
@@ -133,6 +142,7 @@ PHP_METHOD(Cursor, kill)
133142
php_phongo_cursor_t *intern;
134143
zend_error_handling error_handling;
135144
int hint;
145+
(void)return_value_ptr; (void)return_value_used;
136146

137147

138148
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
@@ -146,15 +156,18 @@ PHP_METHOD(Cursor, kill)
146156

147157
hint = mongoc_cursor_get_hint(intern->result->cursor);
148158
mongoc_client_kill_cursor(intern->result->cursor->client, mongoc_cursor_get_id(intern->result->cursor));
159+
160+
RETURN_NULL();
149161
}
150162
/* }}} */
151-
/* {{{ proto boolean Cursor::setBatchSize(integer $batchSize)
152-
Sets a batch size for the cursor */
163+
/* {{{ proto integer Cursor::setBatchSize(integer $batchSize)
164+
Sets a batch size for the cursor, returning the previous size */
153165
PHP_METHOD(Cursor, setBatchSize)
154166
{
155167
php_phongo_cursor_t *intern;
156168
zend_error_handling error_handling;
157169
long batchSize;
170+
(void)return_value_ptr; (void)return_value_used;
158171

159172

160173
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
@@ -166,6 +179,7 @@ PHP_METHOD(Cursor, setBatchSize)
166179
}
167180
zend_restore_error_handling(&error_handling TSRMLS_CC);
168181

182+
RETVAL_LONG(mongoc_cursor_get_batch_size(intern->result->cursor));
169183
mongoc_cursor_set_batch_size(intern->result->cursor, batchSize);
170184
}
171185
/* }}} */
@@ -175,6 +189,7 @@ PHP_METHOD(Cursor, getBatchSize)
175189
{
176190
php_phongo_cursor_t *intern;
177191
zend_error_handling error_handling;
192+
(void)return_value_ptr; (void)return_value_used;
178193

179194

180195
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
@@ -197,6 +212,7 @@ PHP_METHOD(Cursor, current)
197212
php_phongo_cursor_t *intern;
198213
zend_error_handling error_handling;
199214
zval **data = NULL;
215+
(void)return_value_ptr; (void)return_value_used;
200216

201217

202218
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
@@ -227,6 +243,7 @@ PHP_METHOD(Cursor, key)
227243
{
228244
php_phongo_cursor_t *intern;
229245
zend_error_handling error_handling;
246+
(void)return_value_ptr; (void)return_value_used;
230247

231248

232249
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
@@ -258,6 +275,7 @@ PHP_METHOD(Cursor, next)
258275
{
259276
php_phongo_cursor_t *intern;
260277
zend_error_handling error_handling;
278+
(void)return_value; (void)return_value_ptr; (void)return_value_used;
261279

262280

263281
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
@@ -285,6 +303,7 @@ PHP_METHOD(Cursor, rewind)
285303
{
286304
php_phongo_cursor_t *intern;
287305
zend_error_handling error_handling;
306+
(void)return_value; (void)return_value_ptr; (void)return_value_used;
288307

289308

290309
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
@@ -312,6 +331,7 @@ PHP_METHOD(Cursor, valid)
312331
{
313332
php_phongo_cursor_t *intern;
314333
zend_error_handling error_handling;
334+
(void)return_value_ptr; (void)return_value_used;
315335

316336

317337
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC);
@@ -334,18 +354,6 @@ PHP_METHOD(Cursor, valid)
334354
}
335355
/* }}} */
336356

337-
/**
338-
* Cursor used to iterate through results of an executed Query or Command.
339-
*
340-
* The iteration and internal logic of Query and Command cursors is very
341-
* similar. The cursor ID and first batch of results, originating from either
342-
* the OP_REPLY message or command result document), will be used to construct
343-
* this object.
344-
*
345-
* While this Cursor object must be initialized internally, the class itself may
346-
* be extended to provide custom Cursor behaviors (e.g. return documents as
347-
* BSON, hydrated classes, stdClass objects).
348-
*/
349357
/* {{{ MongoDB\Driver\Cursor */
350358

351359
ZEND_BEGIN_ARG_INFO_EX(ai_Cursor___construct, 0, 0, 3)
@@ -425,32 +433,164 @@ static void php_phongo_cursor_free_object(void *object TSRMLS_DC) /* {{{ */
425433
zend_object_value php_phongo_cursor_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
426434
{
427435
zend_object_value retval;
428-
php_phongo_cursor_t *intern;
436+
php_phongo_cursor_t *intern = NULL;
429437

430-
intern = (php_phongo_cursor_t *)emalloc(sizeof(php_phongo_cursor_t));
431-
memset(intern, 0, sizeof(php_phongo_cursor_t));
438+
intern = (php_phongo_cursor_t *)ecalloc(1, sizeof *intern);
432439

433440
zend_object_std_init(&intern->std, class_type TSRMLS_CC);
434441
object_properties_init(&intern->std, class_type);
435442

436443
retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_cursor_free_object, NULL TSRMLS_CC);
437-
retval.handlers = phongo_get_std_object_handlers();
444+
retval.handlers = &php_phongo_handler_cursor;
438445

439446
return retval;
440447
} /* }}} */
448+
449+
void php_phongo_read_preference_to_zval(zval *retval, mongoc_read_prefs_t *read_prefs) /* {{{ */
450+
{
451+
452+
array_init_size(retval, 2);
453+
454+
add_assoc_long_ex(retval, ZEND_STRS("mode"), read_prefs->mode);
455+
if (read_prefs->tags.len) {
456+
php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER;
457+
458+
MAKE_STD_ZVAL(state.zchild);
459+
bson_to_zval(bson_get_data(&read_prefs->tags), read_prefs->tags.len, &state);
460+
add_assoc_zval_ex(retval, ZEND_STRS("tags"), state.zchild);
461+
} else {
462+
add_assoc_null_ex(retval, ZEND_STRS("tags"));
463+
}
464+
} /* }}} */
465+
466+
void php_phongo_result_to_zval(zval *retval, php_phongo_result_t *result) /* {{{ */
467+
{
468+
469+
array_init_size(retval, 4);
470+
471+
if (result->cursor) {
472+
zval *cursor = NULL;
473+
474+
MAKE_STD_ZVAL(cursor);
475+
array_init_size(cursor, 16);
476+
477+
add_assoc_long_ex(cursor, ZEND_STRS("stamp"), result->cursor->stamp);
478+
479+
#define _ADD_BOOL(z, field) add_assoc_bool_ex(z, ZEND_STRS(#field), result->cursor->field)
480+
_ADD_BOOL(cursor, is_command);
481+
_ADD_BOOL(cursor, sent);
482+
_ADD_BOOL(cursor, done);
483+
_ADD_BOOL(cursor, failed);
484+
_ADD_BOOL(cursor, end_of_event);
485+
_ADD_BOOL(cursor, in_exhaust);
486+
_ADD_BOOL(cursor, redir_primary);
487+
_ADD_BOOL(cursor, has_fields);
488+
#undef _ADD_BOOL
489+
490+
{
491+
php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER;
492+
493+
MAKE_STD_ZVAL(state.zchild);
494+
bson_to_zval(bson_get_data(&result->cursor->query), result->cursor->query.len, &state);
495+
add_assoc_zval_ex(cursor, ZEND_STRS("query"), state.zchild);
496+
}
497+
{
498+
php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER;
499+
500+
MAKE_STD_ZVAL(state.zchild);
501+
bson_to_zval(bson_get_data(&result->cursor->fields), result->cursor->fields.len, &state);
502+
add_assoc_zval_ex(cursor, ZEND_STRS("fields"), state.zchild);
503+
}
504+
{
505+
zval *read_preference = NULL;
506+
507+
MAKE_STD_ZVAL(read_preference);
508+
php_phongo_read_preference_to_zval(read_preference, result->cursor->read_prefs);
509+
add_assoc_zval_ex(cursor, ZEND_STRS("read_preference"), read_preference);
510+
}
511+
512+
#define _ADD_INT(z, field) add_assoc_long_ex(z, ZEND_STRS(#field), result->cursor->field)
513+
_ADD_INT(cursor, flags);
514+
_ADD_INT(cursor, skip);
515+
_ADD_INT(cursor, limit);
516+
_ADD_INT(cursor, count);
517+
_ADD_INT(cursor, batch_size);
518+
#undef _ADD_INT
519+
520+
add_assoc_string_ex(cursor, ZEND_STRS("ns"), result->cursor->ns, 1);
521+
{
522+
php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER;
523+
524+
MAKE_STD_ZVAL(state.zchild);
525+
bson_to_zval(bson_get_data(result->cursor->current), result->cursor->current->len, &state);
526+
add_assoc_zval_ex(cursor, ZEND_STRS("current_doc"), state.zchild);
527+
}
528+
add_assoc_zval_ex(retval, ZEND_STRS("cursor"), cursor);
529+
} else {
530+
add_assoc_null_ex(retval, ZEND_STRS("cursor"));
531+
}
532+
533+
if (result->firstBatch) {
534+
php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER;
535+
536+
MAKE_STD_ZVAL(state.zchild);
537+
bson_to_zval(bson_get_data(result->firstBatch), result->firstBatch->len, &state);
538+
add_assoc_zval_ex(retval, ZEND_STRS("firstBatch"), state.zchild);
539+
} else {
540+
add_assoc_null_ex(retval, ZEND_STRS("firstBatch"));
541+
}
542+
add_assoc_long_ex(retval, ZEND_STRS("hint"), result->hint);
543+
add_assoc_bool_ex(retval, ZEND_STRS("is_command_cursor"), result->is_command_cursor);
544+
545+
} /* }}} */
546+
547+
HashTable *php_phongo_cursor_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */
548+
{
549+
php_phongo_cursor_t *intern;
550+
zval retval = zval_used_for_init;
551+
552+
553+
*is_temp = 1;
554+
intern = (php_phongo_cursor_t *)zend_object_store_get_object(object TSRMLS_CC);
555+
556+
array_init_size(&retval, 2);
557+
558+
if (!intern->it) {
559+
zend_class_entry *ce;
560+
561+
ce = Z_OBJCE_P(object);
562+
intern->it = (phongo_cursor_it *)ce->get_iterator(ce, object, 0 TSRMLS_CC);
563+
}
564+
add_assoc_long_ex(&retval, ZEND_STRS("current_index"), intern->it->current);
565+
566+
567+
if (intern->result) {
568+
zval *result = NULL;
569+
570+
MAKE_STD_ZVAL(result);
571+
php_phongo_result_to_zval(result, intern->result);
572+
add_assoc_zval_ex(&retval, ZEND_STRS("result"), result);
573+
}
574+
575+
return Z_ARRVAL(retval);
576+
577+
} /* }}} */
441578
/* }}} */
442579

443580
/* {{{ PHP_MINIT_FUNCTION */
444581
PHP_MINIT_FUNCTION(Cursor)
445582
{
446-
(void)type; /* We don't care if we are loaded via dl() or extension= */
583+
(void)type; (void)module_number;
447584
zend_class_entry ce;
448585

449586
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "Cursor", php_phongo_cursor_me);
450-
ce.create_object = php_phongo_cursor_create_object;
451587
php_phongo_cursor_ce = zend_register_internal_class(&ce TSRMLS_CC);
588+
php_phongo_cursor_ce->create_object = php_phongo_cursor_create_object;
452589
php_phongo_cursor_ce->get_iterator = phongo_cursor_get_iterator;
453590

591+
memcpy(&php_phongo_handler_cursor, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
592+
php_phongo_handler_cursor.get_debug_info = php_phongo_cursor_get_debug_info;
593+
454594
zend_class_implements(php_phongo_cursor_ce TSRMLS_CC, 1, spl_ce_Iterator);
455595

456596

tests/functional/cursor-001.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ var_dump(
4040
<?php exit(0); ?>
4141
--EXPECT--
4242
int(0)
43-
NULL
43+
int(0)
4444
int(15)
4545
bool(true)
4646
abernathy.audrey
@@ -144,7 +144,7 @@ ypredovic
144144
ywyman
145145
zstanton
146146
int(15)
147-
NULL
147+
int(15)
148148
int(15)
149149
bool(true)
150150
===DONE===

0 commit comments

Comments
 (0)