Hi,

I'm using Propel in a master/slave environment and I've noticed a possible issue with how Propel handles reads.

// i'd expect this to use master for ALL queries, not just rights
Propel::setForceMasterConnection(true);

// gets the write connection (i.e master);
$conn = Propel::getConnection();

// I'd expect this query to hit the master since Propel has been forced to use the master, but it hits the slave
$car = CarPeer::retrieveByPk(1);

Now I can easily get around this for this query by passing in $conn to
retreiveByPk() like so:

// this will hit the master
$car = CarPeer::retrieveByPk(1, $conn);

Which I guess is fine, but it gets a bit ugly needing to pass $conn around to every accessor method.

Another issue is if you have a custom method which accesses a fk. If I had this method in my Car class:

public function changeEngine(EngineType $newEngine)
{
    // this will access the foreign key for EngineType, and if it hasn't been loading already, it'll hit the slave
    // even when forceMasterConnection is set to TRUE. Only way to get around this is the pass in
    // $con to this method as well

    if ($this->getEngineType()->isChangeable())
        $this->setEngineType($newEngine);
}

So, my suggestion is the tweak the handling of connections for master/slave setups.

This is the code used currently in SELECT methods:

if ($con === null) {
    $con = Propel::getConnection(BidPeer::DATABASE_NAME, Propel::CONNECTION_READ);
}


[Option 1]

Use ternary operator in relevant methods:

if ($con === null) {
    $con = Propel::getConnection(BidPeer::DATABASE_NAME, (Propel::getForceMasterConnection() ? Propel::CONNECTION_WRITE : Propel::CONNECTION_READ) );
}

[Option 2]

Add new methods which way be easier to extend in the future. In the Propel class:

/**
 * Returns the connection to be used when writing
 *
 * @return PropelPDO
 */
public static function getWriteConnection($database)
{
   
Propel::getConnection($database, Propel::CONNECTION_WRITE);
}

/**
 * Returns the connection to be used when selecting from the db.
 *
 * This method will have different results based on the value of Propel::$forceMasterConnection has been
 * set in a master/slave environment.
 *
 * @return PropelPDO
 */
public static function getReadConnection($database)
{
    if (Propel::getForceMasterConnection()) {
        // master has been forced, use write connection
        return self::getWriteConnection($database);
    }

    // master not forced, so use read connection
   
Propel::getConnection($database, Propel::CONNECTION_READ);
}

Then the usage in query methods is a bit simpler:

SELECT methods:

if ($con === null) {
    $con = Propel::getReadConnection();
}

INSERT/UPDATE/DELETE methods:

if ($con === null) {
    $con = Propel::getWriteConnection();
}



Thoughts?