/* {{{ 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); } }
/* * 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; }