Skip to content

Commit d3687d8

Browse files
committed
Inline single-use iterator handlers
1 parent b3ff8b6 commit d3687d8

File tree

1 file changed

+66
-100
lines changed

1 file changed

+66
-100
lines changed

src/MongoDB/Cursor.c

Lines changed: 66 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -52,101 +52,6 @@ static void php_phongo_cursor_free_current(php_phongo_cursor_t* cursor) /* {{{ *
5252
}
5353
} /* }}} */
5454

55-
/* {{{ MongoDB\Driver\Cursor iterator handlers */
56-
static int php_phongo_cursor_valid(php_phongo_cursor_t* cursor) /* {{{ */
57-
{
58-
if (!Z_ISUNDEF(cursor->visitor_data.zchild)) {
59-
return SUCCESS;
60-
}
61-
62-
return FAILURE;
63-
} /* }}} */
64-
65-
static void php_phongo_cursor_get_current_key(php_phongo_cursor_t* cursor, zval* key) /* {{{ */
66-
{
67-
if (Z_ISUNDEF(cursor->visitor_data.zchild)) {
68-
ZVAL_NULL(key);
69-
return;
70-
}
71-
72-
ZVAL_LONG(key, cursor->current);
73-
} /* }}} */
74-
75-
static zval* php_phongo_cursor_get_current_data(php_phongo_cursor_t* cursor) /* {{{ */
76-
{
77-
return &cursor->visitor_data.zchild;
78-
} /* }}} */
79-
80-
static void php_phongo_cursor_move_forward(php_phongo_cursor_t* cursor) /* {{{ */
81-
{
82-
const bson_t* doc;
83-
84-
php_phongo_cursor_free_current(cursor);
85-
86-
/* If the cursor has already advanced, increment its position. Otherwise,
87-
* the first call to mongoc_cursor_next() will be made below and we should
88-
* leave its position at zero. */
89-
if (cursor->advanced) {
90-
cursor->current++;
91-
} else {
92-
cursor->advanced = true;
93-
}
94-
95-
if (mongoc_cursor_next(cursor->cursor, &doc)) {
96-
if (!php_phongo_bson_to_zval_ex(bson_get_data(doc), doc->len, &cursor->visitor_data)) {
97-
/* Free invalid result, but don't return as we want to free the
98-
* session if the cursor is exhausted. */
99-
php_phongo_cursor_free_current(cursor);
100-
}
101-
} else {
102-
bson_error_t error = { 0 };
103-
const bson_t* doc = NULL;
104-
105-
if (mongoc_cursor_error_document(cursor->cursor, &error, &doc)) {
106-
/* Intentionally not destroying the cursor as it will happen
107-
* naturally now that there are no more results */
108-
phongo_throw_exception_from_bson_error_t_and_reply(&error, doc);
109-
}
110-
}
111-
112-
php_phongo_cursor_free_session_if_exhausted(cursor);
113-
} /* }}} */
114-
115-
static void php_phongo_cursor_rewind(php_phongo_cursor_t* cursor) /* {{{ */
116-
{
117-
const bson_t* doc;
118-
119-
/* If the cursor was never advanced (e.g. command cursor), do so now */
120-
if (!cursor->advanced) {
121-
cursor->advanced = true;
122-
123-
if (!phongo_cursor_advance_and_check_for_error(cursor->cursor)) {
124-
/* Exception should already have been thrown */
125-
return;
126-
}
127-
}
128-
129-
if (cursor->current > 0) {
130-
phongo_throw_exception(PHONGO_ERROR_LOGIC, "Cursors cannot rewind after starting iteration");
131-
return;
132-
}
133-
134-
php_phongo_cursor_free_current(cursor);
135-
136-
doc = mongoc_cursor_current(cursor->cursor);
137-
138-
if (doc) {
139-
if (!php_phongo_bson_to_zval_ex(bson_get_data(doc), doc->len, &cursor->visitor_data)) {
140-
/* Free invalid result, but don't return as we want to free the
141-
* session if the cursor is exhausted. */
142-
php_phongo_cursor_free_current(cursor);
143-
}
144-
}
145-
146-
php_phongo_cursor_free_session_if_exhausted(cursor);
147-
} /* }}} */
148-
/* }}} */
149-
15055
/* {{{ proto void MongoDB\Driver\Cursor::setTypeMap(array $typemap)
15156
Sets a type map to use for BSON unserialization */
15257
static PHP_METHOD(Cursor, setTypeMap)
@@ -314,7 +219,7 @@ PHP_METHOD(Cursor, current)
314219
}
315220
zend_restore_error_handling(&error_handling);
316221

317-
data = php_phongo_cursor_get_current_data(intern);
222+
data = &intern->visitor_data.zchild;
318223

319224
if (Z_ISUNDEF_P(data)) {
320225
RETURN_NULL();
@@ -335,13 +240,18 @@ PHP_METHOD(Cursor, key)
335240
}
336241
zend_restore_error_handling(&error_handling);
337242

338-
php_phongo_cursor_get_current_key(intern, return_value);
243+
if (Z_ISUNDEF(intern->visitor_data.zchild)) {
244+
RETURN_NULL();
245+
}
246+
247+
RETURN_LONG(intern->current);
339248
}
340249

341250
PHP_METHOD(Cursor, next)
342251
{
343252
zend_error_handling error_handling;
344253
php_phongo_cursor_t* intern = Z_CURSOR_OBJ_P(getThis());
254+
const bson_t* doc;
345255

346256
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
347257
if (zend_parse_parameters_none() == FAILURE) {
@@ -350,7 +260,35 @@ PHP_METHOD(Cursor, next)
350260
}
351261
zend_restore_error_handling(&error_handling);
352262

353-
php_phongo_cursor_move_forward(intern);
263+
php_phongo_cursor_free_current(intern);
264+
265+
/* If the intern has already advanced, increment its position. Otherwise,
266+
* the first call to mongoc_cursor_next() will be made below and we should
267+
* leave its position at zero. */
268+
if (intern->advanced) {
269+
intern->current++;
270+
} else {
271+
intern->advanced = true;
272+
}
273+
274+
if (mongoc_cursor_next(intern->cursor, &doc)) {
275+
if (!php_phongo_bson_to_zval_ex(bson_get_data(doc), doc->len, &intern->visitor_data)) {
276+
/* Free invalid result, but don't return as we want to free the
277+
* session if the intern is exhausted. */
278+
php_phongo_cursor_free_current(intern);
279+
}
280+
} else {
281+
bson_error_t error = { 0 };
282+
const bson_t* doc = NULL;
283+
284+
if (mongoc_cursor_error_document(intern->cursor, &error, &doc)) {
285+
/* Intentionally not destroying the intern as it will happen
286+
* naturally now that there are no more results */
287+
phongo_throw_exception_from_bson_error_t_and_reply(&error, doc);
288+
}
289+
}
290+
291+
php_phongo_cursor_free_session_if_exhausted(intern);
354292
}
355293

356294
PHP_METHOD(Cursor, valid)
@@ -365,13 +303,14 @@ PHP_METHOD(Cursor, valid)
365303
}
366304
zend_restore_error_handling(&error_handling);
367305

368-
RETURN_BOOL(php_phongo_cursor_valid(intern) == SUCCESS);
306+
RETURN_BOOL(!Z_ISUNDEF(intern->visitor_data.zchild));
369307
}
370308

371309
PHP_METHOD(Cursor, rewind)
372310
{
373311
zend_error_handling error_handling;
374312
php_phongo_cursor_t* intern = Z_CURSOR_OBJ_P(getThis());
313+
const bson_t* doc;
375314

376315
zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
377316
if (zend_parse_parameters_none() == FAILURE) {
@@ -380,7 +319,34 @@ PHP_METHOD(Cursor, rewind)
380319
}
381320
zend_restore_error_handling(&error_handling);
382321

383-
php_phongo_cursor_rewind(intern);
322+
/* If the intern was never advanced (e.g. command intern), do so now */
323+
if (!intern->advanced) {
324+
intern->advanced = true;
325+
326+
if (!phongo_cursor_advance_and_check_for_error(intern->cursor)) {
327+
/* Exception should already have been thrown */
328+
return;
329+
}
330+
}
331+
332+
if (intern->current > 0) {
333+
phongo_throw_exception(PHONGO_ERROR_LOGIC, "Cursors cannot rewind after starting iteration");
334+
return;
335+
}
336+
337+
php_phongo_cursor_free_current(intern);
338+
339+
doc = mongoc_cursor_current(intern->cursor);
340+
341+
if (doc) {
342+
if (!php_phongo_bson_to_zval_ex(bson_get_data(doc), doc->len, &intern->visitor_data)) {
343+
/* Free invalid result, but don't return as we want to free the
344+
* session if the intern is exhausted. */
345+
php_phongo_cursor_free_current(intern);
346+
}
347+
}
348+
349+
php_phongo_cursor_free_session_if_exhausted(intern);
384350
}
385351

386352
/* {{{ MongoDB\Driver\Cursor function entries */

0 commit comments

Comments
 (0)