예제 #1
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);
  }
}
예제 #2
0
/*
 * this should probably be split into two methods... right now appends the 
 * getlasterror query to the buffer and alloc & inits the cursor zval.
 */
static zval* append_getlasterror(zval *coll, buffer *buf, int safe, int fsync TSRMLS_DC) {
  zval *cmd_ns_z, *cmd, *cursor_z, *temp;
  char *cmd_ns;
  mongo_cursor *cursor;
  mongo_collection *c = (mongo_collection*)zend_object_store_get_object(coll TSRMLS_CC);
  mongo_db *db = (mongo_db*)zend_object_store_get_object(c->parent TSRMLS_CC);
  int response;

  // get "db.$cmd" zval 
  MAKE_STD_ZVAL(cmd_ns_z);
  spprintf(&cmd_ns, 0, "%s.$cmd", Z_STRVAL_P(db->name));
  ZVAL_STRING(cmd_ns_z, cmd_ns, 0);

  // get {"getlasterror" : 1} zval
  MAKE_STD_ZVAL(cmd);
  array_init(cmd);
  add_assoc_long(cmd, "getlasterror", 1);

  if (safe == 1) {
    zval *w = zend_read_property(mongo_ce_Collection, coll, "w", strlen("w"), NOISY TSRMLS_CC);
    safe = Z_LVAL_P(w);
  }

  if (safe > 1) {
    zval *wtimeout;

    add_assoc_long(cmd, "w", safe); 

    wtimeout = zend_read_property(mongo_ce_Collection, coll, "wtimeout", strlen("wtimeout"), NOISY TSRMLS_CC);
    add_assoc_long(cmd, "wtimeout", Z_LVAL_P(wtimeout));
  }
  if (fsync) {
    add_assoc_bool(cmd, "fsync", 1);
  }

  // get cursor
  MAKE_STD_ZVAL(cursor_z);
  object_init_ex(cursor_z, mongo_ce_Cursor);

  MAKE_STD_ZVAL(temp);
  ZVAL_NULL(temp);
  MONGO_METHOD2(MongoCursor, __construct, temp, cursor_z, c->link, cmd_ns_z);
  zval_ptr_dtor(&temp);
  if (EG(exception)) {
    zval_ptr_dtor(&cmd_ns_z);
    return 0;
  }

  cursor = (mongo_cursor*)zend_object_store_get_object(cursor_z TSRMLS_CC);

  cursor->limit = -1;
  zval_ptr_dtor(&cursor->query);
  // cmd is now part of cursor, so it shouldn't be dtored until cursor is
  cursor->query = cmd;

  // append the query
  response = php_mongo_write_query(buf, cursor TSRMLS_CC);
  zval_ptr_dtor(&cmd_ns_z);

  if (FAILURE == response) {
    return 0;
  }

  return cursor_z;
}