Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed PHP-511: Setting slaveOkay on MongoDB doesn't get passed proper…

…ly to MongoCollection.
  • Loading branch information...
commit da737dae8a033f3c15a7d9cb3e5a2ad7b80f9073 1 parent 73adbe4
@derickr authored
View
9 collection.c
@@ -568,10 +568,10 @@ PHP_METHOD(MongoCollection, batchInsert) {
PHP_METHOD(MongoCollection, find)
{
zval *query = 0, *fields = 0;
- mongo_read_preference rp;
mongo_collection *c;
mongo_link *link;
zval temp;
+ mongo_cursor *cursor;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|zz", &query, &fields) == FAILURE) {
return;
@@ -585,8 +585,6 @@ PHP_METHOD(MongoCollection, find)
object_init_ex(return_value, mongo_ce_Cursor);
- /* save & replace slave_okay */
- mongo_read_preference_copy(&link->servers->read_pref, &rp);
mongo_read_preference_replace(&c->read_pref, &link->servers->read_pref);
/* TODO: Don't call an internal function like this, but add a new C-level
@@ -601,8 +599,9 @@ PHP_METHOD(MongoCollection, find)
MONGO_METHOD4(MongoCursor, __construct, &temp, return_value, c->link, c->ns, query, fields);
}
- mongo_read_preference_replace(&rp, &link->servers->read_pref);
- mongo_read_preference_dtor(&rp);
+ /* add read preferences to cursor */
+ cursor = (mongo_cursor*)zend_object_store_get_object(return_value TSRMLS_CC);
+ mongo_read_preference_replace(&c->read_pref, &cursor->read_pref);
}
PHP_METHOD(MongoCollection, findOne) {
View
16 cursor.c
@@ -253,6 +253,11 @@ PHP_METHOD(MongoCursor, __construct) {
cursor->resource = zlink;
zval_add_ref(&zlink);
+ /* Initialize read_pref to empty */
+ cursor->read_pref.type = MONGO_RP_PRIMARY;
+ cursor->read_pref.tagset_count = 0;
+ cursor->read_pref.tagsets = NULL;
+
// change ['x', 'y', 'z'] into {'x' : 1, 'y' : 1, 'z' : 1}
if (Z_TYPE_P(zfields) == IS_ARRAY) {
HashPosition pointer;
@@ -824,6 +829,7 @@ int mongo_cursor__do_query(zval *this_ptr, zval *return_value TSRMLS_DC) {
zval *errmsg;
char *error_message;
mongo_link *link;
+ mongo_read_preference rp;
cursor = (mongo_cursor*)zend_object_store_get_object(getThis() TSRMLS_CC);
if (!cursor) {
@@ -840,6 +846,10 @@ int mongo_cursor__do_query(zval *this_ptr, zval *return_value TSRMLS_DC) {
return FAILURE;
}
+ /* store the link's read preference to backup, and overwrite with the collection's read preferences */
+ mongo_read_preference_copy(&link->servers->read_pref, &rp);
+ mongo_read_preference_replace(&cursor->read_pref, &link->servers->read_pref);
+
/* Sets the wire protocol flag to allow reading from a secondary. The read
* preference spec states: "slaveOk remains as a bit in the wire protocol
* and drivers will set this bit to 1 for all reads except with PRIMARY
@@ -860,6 +870,10 @@ int mongo_cursor__do_query(zval *this_ptr, zval *return_value TSRMLS_DC) {
* append_getlasterror, where this has to be done too. */
cursor->connection = mongo_get_read_write_connection(link->manager, link->servers, MONGO_CON_FLAG_READ, (char**) &error_message);
+ /* restore read preferences from backup */
+ mongo_read_preference_replace(&rp, &link->servers->read_pref);
+ mongo_read_preference_dtor(&rp);
+
if (!cursor->connection && error_message) {
efree(buf.start);
zend_throw_exception(mongo_ce_ConnectionException, error_message, 71 TSRMLS_CC);
@@ -1649,6 +1663,8 @@ void php_mongo_cursor_free(void *object TSRMLS_DC) {
if (cursor->resource) zval_ptr_dtor(&cursor->resource);
+ mongo_read_preference_dtor(&cursor->read_pref);
+
zend_object_std_dtor(&cursor->std TSRMLS_CC);
efree(cursor);
View
2  php_mongo.h
@@ -404,6 +404,8 @@ typedef struct {
zval *current;
int retry;
+ mongo_read_preference read_pref;
+
int dead;
} mongo_cursor;
View
51 tests/replicaset/bug00511.phpt
@@ -0,0 +1,51 @@
+--TEST--
+Test for PHP-511: Setting slaveOkay on MongoDB doesn't get passed properly to MongoCollection
+--SKIPIF--
+<?php require_once dirname(__FILE__) ."/skipif.inc"; ?>
+--FILE--
+<?php
+$mentions = array();
+require_once dirname(__FILE__) . "/../utils.inc";
+
+$m = new Mongo("mongodb://localhost:13000", array("replicaSet" => true));
+$db = $m->test;
+
+MongoLog::setModule( MongoLog::RS );
+MongoLog::setLevel( MongoLog::FINE );
+MongoLog::setCallback( function($a, $b, $message) { if (preg_match('/connection: type: ([A-Z]+),/', $message, $m )) { @$GLOBALS['mentions'][$m[1]]++; }; } );
+$db->setSlaveOkay(true);
+
+$mentions = array();
+
+// Normal find
+$ret = $db->safe->find(array("doc" => 1));
+iterator_to_array($ret);
+var_dump($mentions); $mentions = array();
+
+// Force primary for command
+$db->setProfilingLevel(42);
+var_dump($mentions); $mentions = array();
+
+// Normal find
+$ret = $db->safe->find(array("doc" => 1));
+iterator_to_array($ret);
+var_dump($mentions); $mentions = array();
+?>
+--EXPECTF--
+Deprecated: Function MongoDB::setSlaveOkay() is deprecated in %sbug00511.php on line %d
+array(2) {
+ ["PRIMARY"]=>
+ int(3)
+ ["SECONDARY"]=>
+ int(3)
+}
+array(1) {
+ ["PRIMARY"]=>
+ int(6)
+}
+array(2) {
+ ["PRIMARY"]=>
+ int(3)
+ ["SECONDARY"]=>
+ int(3)
+}
Please sign in to comment.
Something went wrong with that request. Please try again.