示例#1
0
/* {{{ MongoCursor->next
 */
PHP_METHOD(MongoCursor, next) {
  zval has_next;
  mongo_cursor *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;
  }

  // destroy old current
  if (cursor->current) {
    zval_ptr_dtor(&cursor->current);
    cursor->current = 0;
  }

  // check for results
  MONGO_METHOD(MongoCursor, hasNext)(0, &has_next, NULL, getThis(), 0 TSRMLS_CC);
  if (!Z_BVAL(has_next)) {
    // we're out of results
    RETURN_NULL();
  }

  // we got more results
  if (cursor->at < cursor->num) {
    zval **err;
    MAKE_STD_ZVAL(cursor->current);
    array_init(cursor->current);
    cursor->buf.pos = (unsigned char*)bson_to_zval((char*)cursor->buf.pos, Z_ARRVAL_P(cursor->current) TSRMLS_CC);

    // increment cursor position
    cursor->at++;

    // check for err
    if (cursor->num == 1 &&
        zend_hash_find(Z_ARRVAL_P(cursor->current), "$err", 5, (void**)&err) == SUCCESS) {
      zend_throw_exception(mongo_ce_CursorException, Z_STRVAL_PP(err), 0 TSRMLS_CC);
      RETURN_FALSE;
    }
  }

  RETURN_NULL();
}
示例#2
0
/* {{{ MongoCursor->next
 */
PHP_METHOD(MongoCursor, next) {
  zval has_next;
  mongo_cursor *cursor;

  PHP_MONGO_GET_CURSOR(getThis());

  if (!cursor->started_iterating) {
    MONGO_METHOD(MongoCursor, doQuery, return_value, getThis());
    if (EG(exception)) {
      return;
    }
    cursor->started_iterating = 1;
  }

  // destroy old current
  if (cursor->current) {
    zval_ptr_dtor(&cursor->current);
    cursor->current = 0;
  }

  // check for results
  MONGO_METHOD(MongoCursor, hasNext, &has_next, getThis());
  if (EG(exception)) {
    return;
  }
  if (!Z_BVAL(has_next)) {
    // we're out of results
    RETURN_NULL();
  }

  // we got more results
  if (cursor->at < cursor->num) {
    zval **err;
    MAKE_STD_ZVAL(cursor->current);
    array_init(cursor->current);
    cursor->buf.pos = bson_to_zval((char*)cursor->buf.pos, Z_ARRVAL_P(cursor->current) TSRMLS_CC);

    if (EG(exception)) {
      zval_ptr_dtor(&cursor->current);
      cursor->current = 0;
      return;
    }

    // increment cursor position
    cursor->at++;

    // check for err
    if (cursor->num == 1 &&
        zend_hash_find(Z_ARRVAL_P(cursor->current), "$err", strlen("$err")+1, (void**)&err) == SUCCESS) {
      zval **code_z;
      // default error code
      int code = 4;
      
      if (zend_hash_find(Z_ARRVAL_P(cursor->current), "code", strlen("code")+1, (void**)&code_z) == SUCCESS) {
        // check for not master
        if (Z_TYPE_PP(code_z) == IS_LONG) {
          code = Z_LVAL_PP(code_z);
        }
        else if (Z_TYPE_PP(code_z) == IS_DOUBLE) {
          code = (int)Z_DVAL_PP(code_z);
        }
        // else code == 4
        
        // this shouldn't be necessary after 1.7.* is standard, it forces
        // failover in case the master steps down.
        // not master: 10107
        // not master and slaveok=false (more recent): 13435
        // not master or secondary: 13436
        if (cursor->link->rs && (code == 10107 || code == 13435 || code == 13436)) {
          php_mongo_disconnect_server(cursor->server);
        }
      }

      zend_throw_exception(mongo_ce_CursorException, Z_STRVAL_PP(err), code TSRMLS_CC);
      zval_ptr_dtor(&cursor->current);
      cursor->current = 0;
      RETURN_FALSE;
    }
  }

  RETURN_NULL();
}