Skip to content

Commit 0232784

Browse files
committed
Merge pull request #37
2 parents f40aa95 + 70b7110 commit 0232784

13 files changed

+416
-127
lines changed

php_phongo.c

Lines changed: 39 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -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

252250
void 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

15611556
void 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

php_phongo_classes.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,13 @@ typedef struct {
3737
typedef struct {
3838
zend_object std;
3939
mongoc_cursor_t *cursor;
40-
bson_t *firstBatch;
4140
mongoc_client_t *client;
4241
int server_id;
43-
zend_bool is_command_cursor;
4442
php_phongo_bson_state visitor_data;
4543
} php_phongo_cursor_t;
4644

4745
typedef struct {
4846
zend_object_iterator intern;
49-
bson_iter_t first_batch_iter;
5047
php_phongo_cursor_t *cursor;
5148
long current;
5249
} php_phongo_cursor_iterator;

tests/readPreference/002.phpt

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,8 @@ object(MongoDB\Driver\Cursor)#%d (%d) {
7878
["ns"]=>
7979
string(25) "phongo.readPreference_002"
8080
}
81-
["firstBatch"]=>
82-
NULL
8381
["server_id"]=>
8482
int(1)
85-
["is_command_cursor"]=>
86-
bool(false)
8783
}
8884
object(MongoDB\Driver\Cursor)#%d (%d) {
8985
["cursor"]=>
@@ -146,12 +142,8 @@ object(MongoDB\Driver\Cursor)#%d (%d) {
146142
["ns"]=>
147143
string(25) "phongo.readPreference_002"
148144
}
149-
["firstBatch"]=>
150-
NULL
151145
["server_id"]=>
152146
int(1)
153-
["is_command_cursor"]=>
154-
bool(false)
155147
}
156148
object(MongoDB\Driver\Cursor)#%d (%d) {
157149
["cursor"]=>
@@ -214,12 +206,8 @@ object(MongoDB\Driver\Cursor)#%d (%d) {
214206
["ns"]=>
215207
string(25) "phongo.readPreference_002"
216208
}
217-
["firstBatch"]=>
218-
NULL
219209
["server_id"]=>
220210
int(1)
221-
["is_command_cursor"]=>
222-
bool(false)
223211
}
224212
object(MongoDB\Driver\Cursor)#%d (%d) {
225213
["cursor"]=>
@@ -282,12 +270,8 @@ object(MongoDB\Driver\Cursor)#%d (%d) {
282270
["ns"]=>
283271
string(25) "phongo.readPreference_002"
284272
}
285-
["firstBatch"]=>
286-
NULL
287273
["server_id"]=>
288274
int(1)
289-
["is_command_cursor"]=>
290-
bool(false)
291275
}
292276
object(MongoDB\Driver\Cursor)#%d (%d) {
293277
["cursor"]=>
@@ -350,11 +334,7 @@ object(MongoDB\Driver\Cursor)#%d (%d) {
350334
["ns"]=>
351335
string(25) "phongo.readPreference_002"
352336
}
353-
["firstBatch"]=>
354-
NULL
355337
["server_id"]=>
356338
int(1)
357-
["is_command_cursor"]=>
358-
bool(false)
359339
}
360340
===DONE===
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
--TEST--
2+
MongoDB\Driver\Cursor query result iteration with batchSize requiring getmore with full batches
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"; CLEANUP(STANDALONE) ?>
5+
--FILE--
6+
<?php
7+
require_once __DIR__ . "/../utils/basic.inc";
8+
9+
$manager = new MongoDB\Driver\Manager(STANDALONE);
10+
11+
$bulkWrite = new MongoDB\Driver\BulkWrite;
12+
13+
for ($i = 0; $i < 6; $i++) {
14+
$bulkWrite->insert(array('_id' => $i));
15+
}
16+
17+
$writeResult = $manager->executeBulkWrite(NS, $bulkWrite);
18+
printf("Inserted: %d\n", $writeResult->getInsertedCount());
19+
20+
$cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array(), array('batchSize' => 2)));
21+
22+
foreach ($cursor as $i => $document) {
23+
printf("%d => {_id: %d}\n", $i, $document['_id']);
24+
}
25+
26+
?>
27+
===DONE===
28+
<?php exit(0); ?>
29+
--EXPECT--
30+
Inserted: 6
31+
0 => {_id: 0}
32+
1 => {_id: 1}
33+
2 => {_id: 2}
34+
3 => {_id: 3}
35+
4 => {_id: 4}
36+
5 => {_id: 5}
37+
===DONE===
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
MongoDB\Driver\Cursor query result iteration with batchSize requiring getmore with non-full batches
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"; CLEANUP(STANDALONE) ?>
5+
--FILE--
6+
<?php
7+
require_once __DIR__ . "/../utils/basic.inc";
8+
9+
$manager = new MongoDB\Driver\Manager(STANDALONE);
10+
11+
$bulkWrite = new MongoDB\Driver\BulkWrite;
12+
13+
for ($i = 0; $i < 5; $i++) {
14+
$bulkWrite->insert(array('_id' => $i));
15+
}
16+
17+
$writeResult = $manager->executeBulkWrite(NS, $bulkWrite);
18+
printf("Inserted: %d\n", $writeResult->getInsertedCount());
19+
20+
$cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array(), array('batchSize' => 2)));
21+
22+
foreach ($cursor as $i => $document) {
23+
printf("%d => {_id: %d}\n", $i, $document['_id']);
24+
}
25+
26+
?>
27+
===DONE===
28+
<?php exit(0); ?>
29+
--EXPECT--
30+
Inserted: 5
31+
0 => {_id: 0}
32+
1 => {_id: 1}
33+
2 => {_id: 2}
34+
3 => {_id: 3}
35+
4 => {_id: 4}
36+
===DONE===
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
--TEST--
2+
MongoDB\Driver\Cursor command result iteration with batchSize requiring getmore with full batches
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"; CLEANUP(STANDALONE) ?>
5+
--FILE--
6+
<?php
7+
require_once __DIR__ . "/../utils/basic.inc";
8+
9+
$manager = new MongoDB\Driver\Manager(STANDALONE);
10+
11+
$bulkWrite = new MongoDB\Driver\BulkWrite;
12+
13+
for ($i = 0; $i < 6; $i++) {
14+
$bulkWrite->insert(array('_id' => $i));
15+
}
16+
17+
$writeResult = $manager->executeBulkWrite(NS, $bulkWrite);
18+
printf("Inserted: %d\n", $writeResult->getInsertedCount());
19+
20+
$command = new MongoDB\Driver\Command(array(
21+
'aggregate' => COLLECTION_NAME,
22+
'pipeline' => array(
23+
array('$match' => new stdClass),
24+
),
25+
'cursor' => array('batchSize' => 2),
26+
));
27+
28+
$cursor = $manager->executeCommand(DATABASE_NAME, $command);
29+
30+
foreach ($cursor as $i => $document) {
31+
printf("%d => {_id: %d}\n", $i, $document['_id']);
32+
}
33+
34+
?>
35+
===DONE===
36+
<?php exit(0); ?>
37+
--EXPECT--
38+
Inserted: 6
39+
0 => {_id: 0}
40+
1 => {_id: 1}
41+
2 => {_id: 2}
42+
3 => {_id: 3}
43+
4 => {_id: 4}
44+
5 => {_id: 5}
45+
===DONE===

0 commit comments

Comments
 (0)