/* {{{ MongoCursor->doQuery */ PHP_METHOD(MongoCursor, doQuery) { int sent; mongo_msg_header header; mongo_cursor *cursor; CREATE_BUF(buf, INITIAL_BUF_SIZE); cursor = (mongo_cursor*)zend_object_store_get_object(getThis() TSRMLS_CC); MONGO_CHECK_INITIALIZED(cursor->link, MongoCursor); CREATE_HEADER_WITH_OPTS(buf, cursor->ns, OP_QUERY, cursor->opts); serialize_int(&buf, cursor->skip); serialize_int(&buf, cursor->limit); zval_to_bson(&buf, HASH_P(cursor->query), NO_PREP TSRMLS_CC); if (cursor->fields && zend_hash_num_elements(HASH_P(cursor->fields)) > 0) { zval_to_bson(&buf, HASH_P(cursor->fields), NO_PREP TSRMLS_CC); } serialize_size(buf.start, &buf); // sends sent = mongo_say(cursor->link, &buf TSRMLS_CC); efree(buf.start); if (sent == FAILURE) { zend_throw_exception(mongo_ce_CursorException, "couldn't send query.", 0 TSRMLS_CC); return; } get_reply(cursor TSRMLS_CC); }
/* {{{ MongoCursor::hasNext */ PHP_METHOD(MongoCursor, hasNext) { mongo_msg_header header; buffer buf; int size; mongo_cursor *cursor = (mongo_cursor*)zend_object_store_get_object(getThis() TSRMLS_CC); MONGO_CHECK_INITIALIZED(cursor->link, MongoCursor); if (!cursor->started_iterating) { MONGO_METHOD(MongoCursor, doQuery)(INTERNAL_FUNCTION_PARAM_PASSTHRU); cursor->started_iterating = 1; } if ((cursor->limit > 0 && cursor->at >= cursor->limit) || cursor->num == 0) { RETURN_FALSE; } if (cursor->at < cursor->num) { RETURN_TRUE; } else if (cursor->cursor_id == 0) { RETURN_FALSE; } // we have to go and check with the db size = 34+strlen(cursor->ns); buf.start = (unsigned char*)emalloc(size); buf.pos = buf.start; buf.end = buf.start + size; CREATE_RESPONSE_HEADER(buf, cursor->ns, strlen(cursor->ns), cursor->header.request_id, OP_GET_MORE); serialize_int(&buf, cursor->limit); serialize_long(&buf, cursor->cursor_id); serialize_size(buf.start, &buf); // fails if we're out of elems if(mongo_say(cursor->link, &buf TSRMLS_CC) == FAILURE) { efree(buf.start); RETURN_FALSE; } efree(buf.start); // if we have cursor->at == cursor->num && recv fails, // we're probably just out of results RETURN_BOOL(get_reply(cursor TSRMLS_CC) == SUCCESS); }
/* {{{ MongoCursor->doQuery */ PHP_METHOD(MongoCursor, doQuery) { mongo_cursor *cursor; buffer buf; zval *errmsg; PHP_MONGO_GET_CURSOR(getThis()); CREATE_BUF(buf, INITIAL_BUF_SIZE); if (php_mongo_write_query(&buf, cursor TSRMLS_CC) == FAILURE) { efree(buf.start); return; } MAKE_STD_ZVAL(errmsg); ZVAL_NULL(errmsg); // If slave_okay is set, read from a slave. if ((cursor->link->rs && cursor->opts & SLAVE_OKAY && (cursor->server = php_mongo_get_slave_socket(cursor->link, errmsg TSRMLS_CC)) == 0)) { // ignore errors and reset errmsg zval_ptr_dtor(&errmsg); MAKE_STD_ZVAL(errmsg); ZVAL_NULL(errmsg); } // if getting the slave didn't work (or we're not using a rs), just get master socket if (cursor->server == 0 && (cursor->server = php_mongo_get_socket(cursor->link, errmsg TSRMLS_CC)) == 0) { efree(buf.start); zend_throw_exception(mongo_ce_CursorException, Z_STRVAL_P(errmsg), 14 TSRMLS_CC); zval_ptr_dtor(&errmsg); return; } if (mongo_say(cursor->server->socket, &buf, errmsg TSRMLS_CC) == FAILURE) { php_mongo_disconnect_server(cursor->server); if (Z_TYPE_P(errmsg) == IS_STRING) { zend_throw_exception_ex(mongo_ce_CursorException, 14 TSRMLS_CC, "couldn't send query: %s", Z_STRVAL_P(errmsg)); } else { zend_throw_exception(mongo_ce_CursorException, "couldn't send query", 14 TSRMLS_CC); } efree(buf.start); zval_ptr_dtor(&errmsg); return; } efree(buf.start); if (php_mongo_get_reply(cursor, errmsg TSRMLS_CC) == FAILURE) { zval_ptr_dtor(&errmsg); return; } zval_ptr_dtor(&errmsg); /* we've got something to kill, make a note */ if (cursor->cursor_id != 0) { php_mongo_create_le(cursor, "cursor_list" TSRMLS_CC); } }
/* {{{ MongoCursor::hasNext */ PHP_METHOD(MongoCursor, hasNext) { buffer buf; int size; mongo_cursor *cursor = (mongo_cursor*)zend_object_store_get_object(getThis() TSRMLS_CC); zval *temp; MONGO_CHECK_INITIALIZED(cursor->link, MongoCursor); if (!cursor->started_iterating) { MONGO_METHOD(MongoCursor, doQuery, return_value, getThis()); cursor->started_iterating = 1; } if ((cursor->limit > 0 && cursor->at >= cursor->limit) || cursor->num == 0) { RETURN_FALSE; } if (cursor->at < cursor->num) { RETURN_TRUE; } else if (cursor->cursor_id == 0) { RETURN_FALSE; } // if we have a cursor_id, we should have a server else if (cursor->server == 0) { zend_throw_exception(mongo_ce_CursorException, "Trying to get more, but cannot find server", 18 TSRMLS_CC); return; } // we have to go and check with the db size = 34+strlen(cursor->ns); CREATE_BUF(buf, size); if (FAILURE == php_mongo_write_get_more(&buf, cursor TSRMLS_CC)) { efree(buf.start); return; } MAKE_STD_ZVAL(temp); ZVAL_NULL(temp); if(mongo_say(cursor->server->socket, &buf, temp TSRMLS_CC) == FAILURE) { php_mongo_disconnect_server(cursor->server); efree(buf.start); zend_throw_exception(mongo_ce_CursorException, Z_STRVAL_P(temp), 1 TSRMLS_CC); zval_ptr_dtor(&temp); return; } efree(buf.start); if (php_mongo_get_reply(cursor, temp TSRMLS_CC) != SUCCESS) { zval_ptr_dtor(&temp); return; } zval_ptr_dtor(&temp); if (cursor->cursor_id == 0) { php_mongo_free_cursor_le(cursor, MONGO_CURSOR TSRMLS_CC); } // if cursor_id != 0, server should stay the same if (cursor->flag & 1) { zend_throw_exception(mongo_ce_CursorException, "Cursor not found", 2 TSRMLS_CC); return; } // sometimes we'll have a cursor_id but there won't be any more results if (cursor->at >= cursor->num) { RETURN_FALSE; } // but sometimes there will be else { RETURN_TRUE; } }