Development

Changeset 6433

You must first sign up to be able to contribute.

Changeset 6433

Show
Ignore:
Timestamp:
12/11/07 01:25:59 (1 year ago)
Author:
dwhittle
Message:

dwhittle: merged changes for master/slave in propel 1.3

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/dwhittle/lib/plugins/sfPropelPlugin/lib/vendor/propel/Propel.php

    r6294 r6433  
    11<?php 
    22/* 
    3  *  $Id: Propel.php 842 2007-12-02 16:28:20Z heltem
     3 *  $Id: Propel.php 853 2007-12-10 21:48:31Z abeggchr
    44 * 
    55 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
     
    3838 * @author     Henning P. Schmiedehausen <hps@intermeta.de> (Torque) 
    3939 * @author     Kurt Schrader <kschrader@karmalab.org> (Torque) 
    40  * @version    $Revision: 842
     40 * @version    $Revision: 853
    4141 * @package    propel 
    4242 */ 
     
    9292   */ 
    9393  const VERSION = '1.3.0-dev'; 
     94   
     95  /** 
     96   * The class name for a PDO object 
     97   */ 
     98  const CLASS_PDO = 'PDO'; 
     99   
     100    /** 
     101   * The class name for a PropelPDO object 
     102   */ 
     103  const CLASS_PROPEL_PDO = 'PropelPDO'; 
     104   
     105    /** 
     106   * The class name for a SlavePDO object 
     107   */ 
     108  const CLASS_SLAVE_PDO = 'SlavePDO'; 
    94109 
    95110  /** 
     
    176191    'PropelColumnTypes' => 'propel/util/PropelColumnTypes.php', 
    177192    'PropelPDO' => 'propel/util/PropelPDO.php', 
     193    'SlavePDO' => 'propel/util/SlavePDO.php', 
    178194    'PropelPager' => 'propel/util/PropelPager.php', 
    179195    'PropelDateTime' => 'propel/util/PropelDateTime.php', 
     
    439455    if (!isset(self::$connectionMap[$name])) { 
    440456 
     457      // load connection parameter for master connection 
    441458      $conparams = isset(self::$configuration['datasources'][$name]['connection']) ? self::$configuration['datasources'][$name]['connection'] : null; 
    442459      if ($conparams === null) { 
    443460        throw new PropelException('No connection information in your runtime configuration file for datasource ['.$name.']'); 
    444461      } 
     462       
     463      // initialize master connection 
     464      $con = Propel::initConnection($conparams, $name, Propel::CLASS_PROPEL_PDO); 
     465      self::$connectionMap[$name] = $con; 
     466       
     467      // load any slaves from the config file and add them to the master connection 
     468      $slaveparams = isset(self::$configuration['datasources'][$name]['slaves']) ? self::$configuration['datasources'][$name]['slaves'] : null; 
     469      if ($slaveparams != null) { 
     470        foreach ($slaveparams as $key => $slaveparam) { 
     471          $con->addSlave($slaveparam, $name); 
     472        } 
     473      } 
     474    } 
     475 
     476    return self::$connectionMap[$name]; 
     477  } 
     478   
     479  /** 
     480   * Opens a new PDO connection for passed-in db name. 
     481   * 
     482   * @param      string[] connection paramters 
     483   * @param      name 
     484   * @param      boolean Initialize a PropelPDO (true, default) or a plain PDO (false) 
     485   * 
     486   * @return     object A database connection of the given class (PDO, PropelPDO, SlavePropelPDO) 
     487   * 
     488   * @throws     PropelException - if lower-level exception caught when trying to connect. 
     489   */ 
     490  public static function initConnection($conparams, $name, $class) { 
    445491 
    446492      $dsn = $conparams['dsn']; 
     
    466512        $con = new PropelPDO($dsn, $user, $password, $driver_options); 
    467513        $con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
    468         self::$connectionMap[$name] = $con; 
    469514      } catch (PDOException $e) { 
    470515        throw new PropelException("Unable to open PDO connection", $e); 
     
    488533      $adapter = self::getDB($name); 
    489534      $adapter->initConnection($con, isset($conparams['settings']) && is_array($conparams['settings']) ? $conparams['settings'] : array()); 
    490     } 
    491  
    492     return self::$connectionMap[$name]; 
    493   } 
    494  
    495   /** 
    496    * Sets the connection to use for specified datasource. 
    497    * 
    498    * @param      string $name The datasource name. 
    499    * @param      PropelPDO $con The PDO connection object to use for specified datasource. 
    500    */ 
    501   public static function setConnection($name, PropelPDO $con) 
    502   { 
    503     if ($name === null) { 
    504       $name = self::getDefaultDB(); 
    505     } 
    506     self::$connectionMap[$name] = $con; 
     535       
     536      return $con; 
    507537  } 
    508538 
  • branches/dwhittle/lib/plugins/sfPropelPlugin/lib/vendor/propel/util/PropelPDO.php

    r6037 r6433  
    11<?php 
    22/* 
    3  *  $Id: PropelPDO.php 806 2007-11-15 00:44:47Z david
     3 *  $Id: PropelPDO.php 853 2007-12-10 21:48:31Z abeggchr
    44 * 
    55 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
     
    3636 * @author     Cameron Brunner <cameron.brunner@gmail.com> 
    3737 * @author     Hans Lellelid <hans@xmpl.org> 
     38 * @author     Christian Abegg <abegg.ch@gmail.com> 
    3839 * @since      2006-09-22 
    3940 * @package    propel.util 
     
    4647   */ 
    4748  protected $nestedTransactionCount = 0; 
    48  
     49   
     50  /** 
     51   * Array of slave connections 
     52   *  
     53   * keys: param, name, con (only after initialisation) 
     54     */ 
     55  protected $slaves = array(); 
     56   
     57  /** 
     58     *  A single slave connection 
     59     */ 
     60  protected $slave = null; 
     61   
     62  /** 
     63     *  Use only the master connection 
     64     */ 
     65  protected $useMasterConnection = false; 
     66   
    4967  /** 
    5068   * Gets the current transaction depth. 
     
    141159 
    142160  /** 
    143    * Overrides PDO::prepare() to add logging. 
     161   * Overrides PDO::prepare() to add logging and split r/w queries 
    144162   */ 
    145163  public function prepare($sql, $driver_options = array()) 
    146164  { 
    147165    Propel::log($sql, Propel::LOG_DEBUG); 
     166    if ($this->isForSlave($sql)) { 
     167      if ($slave = $this->getSlave()) { 
     168        return $slave->prepare($sql, $driver_options); 
     169      } 
     170    } 
    148171    return parent::prepare($sql, $driver_options); 
    149172  } 
     173   
     174  /** 
     175     * Overrides PDO::query() to add logging and split r/w queries 
     176     */ 
     177  public function query($sql, $fetch = null, $input3=null, $input4=null) { 
     178    Propel::log($sql, Propel::LOG_DEBUG); 
     179    if ($this->isForSlave($sql)) { 
     180      if ($slave = $this->getSlave()) { 
     181        return $slave->query($sql, $fetch, $input3, $input4); 
     182      } 
     183    } 
     184    return parent::query($sql, $fetch, $input3, $input4); 
     185  } 
     186   
     187  /** 
     188     * Overrides PDO::exec() to add logging and split r/w queries 
     189     */ 
     190  public function exec($sql) { 
     191    Propel::log($sql, Propel::LOG_DEBUG); 
     192    if ($this->isForSlave($sql)) { 
     193      if ($slave = $this->getSlave()) { 
     194        $slave->exec($sql); 
     195      } 
     196    } 
     197    return parent::exec($sql); 
     198  } 
     199 
     200  /** 
     201     * Adds the configuration for a slave connection 
     202     *  
     203     * @param  array slave param from config 
     204     * @param  string name of the connection 
     205     * @return void 
     206     */ 
     207  public function addSlave($slaveparam, $name) { 
     208    $newIndex = count($this->slaves); 
     209    $this->slaves[$newIndex]['param'] = $slaveparam; 
     210    $this->slaves[$newIndex]['name'] = $name; 
     211  } 
     212   
     213  /** 
     214   * Gets one of the slave connections for read only access 
     215   *  
     216   * @return SlavePDO or false if there are no slaves 
     217   */ 
     218  private function getSlave() { 
     219   
     220    if (isset($this->slave)) return $this->slave;   // slave already initialised 
     221    if (count($this->slaves) == 0) return false;  // return the plain PDO object to avoid endless loops 
     222     
     223    $random = mt_rand(0, count($this->slaves)-1); 
     224    if (isset($this->slaves[$random]['con'])) { 
     225      $this->slave = $this->slaves[$random]['con']; 
     226    } 
     227    else { 
     228      $this->slaves[$random]['con'] = Propel::initConnection($this->slaves[$random]['param'], $this->slaves[$random]['name'], Propel::CLASS_SLAVE_PDO); 
     229      $this->slave = $this->slaves[$random]['con']; 
     230    } 
     231    return $this->slave; 
     232  } 
     233   
     234  /** 
     235   * Checks if a sql query should be handled by the slave connection 
     236   *  
     237   * @return boolean 
     238   */ 
     239  private function isForSlave($sql) { 
     240     
     241    // return false if the use of the master connection is forced 
     242    if ($this->useMasterConnection) return false; 
     243 
     244    // return false if a transaction is open 
     245    $opcount = $this->getNestedTransactionCount(); 
     246    if ($opcount > 0) return false; 
     247     
     248    // check if sql is read only 
     249    return $this->isReadOnly($sql); 
     250  } 
     251   
     252  /** 
     253   * Checks if a sql query is read only (e.g. starts with "select") 
     254   *  
     255   * @return boolean 
     256   */ 
     257  public static function isReadOnly($sql) { 
     258     
     259    // analyse sql 
     260    $result = stripos($sql, "SELECT"); 
     261    if ($result === false) { 
     262      // no select found 
     263      return false; 
     264    } 
     265    else if ($result == 0) { 
     266      // sql starts with select 
     267      return true; 
     268    } 
     269    else { 
     270      // select is somewhere else in string 
     271      return false; 
     272    } 
     273  } 
     274   
     275  /** 
     276   * Forces the use of the master connection only 
     277   *  
     278   * @param boolean use master connection only 
     279   * @return void 
     280   */ 
     281  public function setUseMasterConnection($useMasterConnection) { 
     282    if (is_bool($useMasterConnection)) { 
     283      $this->useMasterConnection = $useMasterConnection; 
     284    } 
     285    else throw new PropelException("Parameter of setUseMasterConnection must be boolean"); 
     286  } 
    150287}