Exemplo n.º 1
0
/* {{{ 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);
}
Exemplo n.º 2
0
/* {{{ 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);
}
Exemplo n.º 3
0
/* {{{ 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);
  }
}
Exemplo n.º 4
0
/* {{{ 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;
  }
}