/* {{{ 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); }
/* Allocates and bootstraps a new php_mongo_batch and its mongo_buffer. * The buffer is ready for adding documents as the wire header and command start has been written */ void php_mongo_api_batch_make(mongo_write_batch_object *intern, char *dbname, char *collectionname, php_mongo_write_types type TSRMLS_DC) /* {{{ */ { php_mongo_batch *batch = ecalloc(1, sizeof(php_mongo_batch)); char *cmd_ns; CREATE_BUF(batch->buffer, INITIAL_BUF_SIZE); batch->request_id = MonGlo(request_id); spprintf(&cmd_ns, 0, "%s.$cmd", dbname); batch->container_pos = php_mongo_api_write_header(&batch->buffer, cmd_ns TSRMLS_CC); batch->batch_pos = php_mongo_api_write_start(&batch->buffer, type, collectionname TSRMLS_CC); efree(cmd_ns); if (intern->batch) { intern->batch->next = batch; batch->first = intern->batch->first; intern->batch = batch; } else { intern->batch = batch; batch->first = intern->batch; } }
/* {{{ 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; } }