Manager.php 9.8 KB
Newer Older
doctrine's avatar
doctrine committed
1
<?php
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/* 
 *  $Id$
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software consists of voluntary contributions made by many individuals
 * and is licensed under the LGPL. For more information, see
 * <http://www.phpdoctrine.com>.
 */
21

doctrine's avatar
doctrine committed
22 23 24 25 26 27
/**
 * @package     Doctrine ORM
 * @url         www.phpdoctrine.com
 * @license     LGPL
 * 
 * Doctrine_Manager is the base component of all doctrine based projects. 
zYne's avatar
zYne committed
28
 * It opens and keeps track of all connections (database connections).
doctrine's avatar
doctrine committed
29 30 31
 */
class Doctrine_Manager extends Doctrine_Configurable implements Countable, IteratorAggregate {
    /**
32
     * @var array $connections      an array containing all the opened connections
doctrine's avatar
doctrine committed
33
     */
34
    private $connections   = array();
doctrine's avatar
doctrine committed
35 36 37 38 39
    /**
     * @var integer $index          the incremented index
     */
    private $index      = 0;
    /**
zYne's avatar
zYne committed
40
     * @var integer $currIndex      the current connection index
doctrine's avatar
doctrine committed
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
     */
    private $currIndex  = 0;
    /**
     * @var string $root            root directory
     */
    private $root; 
    /**
     * @var Doctrine_Null $null     Doctrine_Null object, used for extremely fast null value checking
     */
    private $null;

    /**
     * constructor
     */
    private function __construct() {
        $this->root = dirname(__FILE__);
        $this->null = new Doctrine_Null;

        Doctrine_Record::initNullObject($this->null);
        Doctrine_Collection::initNullObject($this->null);
61
        Doctrine_Record_Iterator::initNullObject($this->null);
62
        Doctrine_Validator::initNullObject($this->null);
doctrine's avatar
doctrine committed
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
    }
    /**
     * @return Doctrine_Null
     */
    final public function getNullObject() {
        return $this->null;
    }
    /**
     * setDefaultAttributes
     * sets default attributes
     *
     * @return boolean
     */
    final public function setDefaultAttributes() {
        static $init = false;
        if( ! $init) {
            $init = true;
            $attributes = array(
doctrine's avatar
doctrine committed
81
                        Doctrine::ATTR_FETCHMODE        => Doctrine::FETCH_IMMEDIATE,
doctrine's avatar
doctrine committed
82 83 84
                        Doctrine::ATTR_CACHE            => Doctrine::CACHE_NONE,
                        Doctrine::ATTR_BATCH_SIZE       => 5,
                        Doctrine::ATTR_COLL_LIMIT       => 5,
85
                        Doctrine::ATTR_LISTENER         => new Doctrine_EventListener_Empty(),
doctrine's avatar
doctrine committed
86 87 88 89
                        Doctrine::ATTR_PK_COLUMNS       => array("id"),
                        Doctrine::ATTR_PK_TYPE          => Doctrine::INCREMENT_KEY,
                        Doctrine::ATTR_LOCKMODE         => 1,
                        Doctrine::ATTR_VLD              => false,
90 91
                        Doctrine::ATTR_CREATE_TABLES    => true,
                        Doctrine::ATTR_QUERY_LIMIT      => Doctrine::LIMIT_RECORDS
doctrine's avatar
doctrine committed
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
                        );
            foreach($attributes as $attribute => $value) {
                $old = $this->getAttribute($attribute);
                if($old === null)
                    $this->setAttribute($attribute,$value);
            }
            return true;
        }
        return false;
    }
    /**
     * returns the root directory of Doctrine
     *
     * @return string
     */
    final public function getRoot() {
        return $this->root;
    }
    /**
     * getInstance                  
     * returns an instance of this class
     * (this class uses the singleton pattern)
     *
     * @return Doctrine_Manager
     */
    final public static function getInstance() {
        static $instance;
        if( ! isset($instance))
            $instance = new self();

        return $instance;
    }
124 125 126 127 128 129 130 131 132 133 134 135
    /**
     * install
     * 
     * @return void
     */
    final public function install() {
        $parent = new ReflectionClass('Doctrine_Record');
        $old    = $this->getAttribute(Doctrine::ATTR_CREATE_TABLES);

        $this->attributes[Doctrine::ATTR_CREATE_TABLES] = true;
        foreach(get_declared_classes() as $name) {
            $class = new ReflectionClass($name);
doctrine's avatar
doctrine committed
136

137 138 139 140 141
            if($class->isSubclassOf($parent))
                $obj = new $class();
        }
        $this->attributes[Doctrine::ATTR_CREATE_TABLES] = $old;
    }
doctrine's avatar
doctrine committed
142
    /**
143
     * openConnection
zYne's avatar
zYne committed
144
     * opens a new connection and saves it to Doctrine_Manager->connections
doctrine's avatar
doctrine committed
145 146
     *
     * @param PDO $pdo                      PDO database driver
147
     * @param string $name                  name of the connection, if empty numeric key is used
zYne's avatar
zYne committed
148
     * @return Doctrine_Connection
doctrine's avatar
doctrine committed
149
     */
150
    public function openConnection(PDO $pdo, $name = null) {
doctrine's avatar
doctrine committed
151 152 153 154 155
        // initialize the default attributes
        $this->setDefaultAttributes();

        if($name !== null) {
            $name = (string) $name;
156
            if(isset($this->connections[$name]))
zYne's avatar
zYne committed
157
                throw new Doctrine_Exception("Connection with $name already exists!");
doctrine's avatar
doctrine committed
158 159 160 161 162 163 164
        
        } else {
            $name = $this->index;
            $this->index++;
        }
        switch($pdo->getAttribute(PDO::ATTR_DRIVER_NAME)):
            case "mysql":
zYne's avatar
zYne committed
165
                $this->connections[$name] = new Doctrine_Connection_Mysql($this,$pdo);
doctrine's avatar
doctrine committed
166 167
            break;
            case "sqlite":
zYne's avatar
zYne committed
168
                $this->connections[$name] = new Doctrine_Connection_Sqlite($this,$pdo);
doctrine's avatar
doctrine committed
169 170
            break;
            case "pgsql":
zYne's avatar
zYne committed
171
                $this->connections[$name] = new Doctrine_Connection_Pgsql($this,$pdo);
doctrine's avatar
doctrine committed
172 173
            break;
            case "oci":
zYne's avatar
zYne committed
174
                $this->connections[$name] = new Doctrine_Connection_Oracle($this,$pdo);
doctrine's avatar
doctrine committed
175 176
            break;
            case "mssql":
zYne's avatar
zYne committed
177
                $this->connections[$name] = new Doctrine_Connection_Mssql($this,$pdo);
doctrine's avatar
doctrine committed
178 179
            break;
            case "firebird":
zYne's avatar
zYne committed
180
                $this->connections[$name] = new Doctrine_Connection_Firebird($this,$pdo);
doctrine's avatar
doctrine committed
181 182
            break;
            case "informix":
zYne's avatar
zYne committed
183
                $this->connections[$name] = new Doctrine_Connection_Informix($this,$pdo);
doctrine's avatar
doctrine committed
184 185 186 187 188
            break;
        endswitch;


        $this->currIndex = $name;
189 190 191 192
        return $this->connections[$name];
    }
    public function openSession(PDO $pdo, $name = null) {
        return $this->openConnection($pdo, $name);
doctrine's avatar
doctrine committed
193 194
    }
    /**
zYne's avatar
zYne committed
195
     * getConnection
doctrine's avatar
doctrine committed
196
     * @param integer $index
zYne's avatar
zYne committed
197
     * @return object Doctrine_Connection
doctrine's avatar
doctrine committed
198 199
     * @throws InvalidKeyException
     */
200 201
    public function getConnection($index) {
        if( ! isset($this->connections[$index]))
doctrine's avatar
doctrine committed
202 203 204
            throw new InvalidKeyException();

        $this->currIndex = $index;
205
        return $this->connections[$index];
doctrine's avatar
doctrine committed
206
    }
207 208
    public function getSession($index) { return $this->getConnection($index); }

doctrine's avatar
doctrine committed
209
    /**
zYne's avatar
zYne committed
210
     * closes the connection
doctrine's avatar
doctrine committed
211
     *
zYne's avatar
zYne committed
212
     * @param Doctrine_Connection $connection
doctrine's avatar
doctrine committed
213 214
     * @return void
     */
zYne's avatar
zYne committed
215 216 217
    public function closeConnection(Doctrine_Connection $connection) {
        $connection->close();
        unset($connection);
doctrine's avatar
doctrine committed
218
    }
zYne's avatar
zYne committed
219
    public function closeSession(Doctrine_Connection $connection) { $this->closeConnection($connection); }
doctrine's avatar
doctrine committed
220
    /**
221 222
     * getConnections
     * returns all opened connections
doctrine's avatar
doctrine committed
223 224 225
     *
     * @return array
     */
226 227 228 229 230
    public function getConnections() {
        return $this->connections;
    }
    public function getSessions() {
        return $this->connections;
doctrine's avatar
doctrine committed
231 232
    }
    /**
233 234
     * setCurrentConnection
     * sets the current connection to $key
doctrine's avatar
doctrine committed
235
     *
236
     * @param mixed $key                        the connection key
doctrine's avatar
doctrine committed
237 238 239
     * @throws InvalidKeyException
     * @return void
     */
240
    public function setCurrentConnection($key) {
doctrine's avatar
doctrine committed
241
        $key = (string) $key;
242
        if( ! isset($this->connections[$key]))
doctrine's avatar
doctrine committed
243 244 245 246
            throw new InvalidKeyException();
        
        $this->currIndex = $key;
    }
247 248 249
    public function setCurrentSession($key) {
        $this->setCurrentConnection($key);
    }
doctrine's avatar
doctrine committed
250 251
    /**
     * count
zYne's avatar
zYne committed
252
     * returns the number of opened connections
doctrine's avatar
doctrine committed
253 254 255 256
     *
     * @return integer
     */
    public function count() {
257
        return count($this->connections);
doctrine's avatar
doctrine committed
258 259 260
    }
    /**
     * getIterator
zYne's avatar
zYne committed
261
     * returns an ArrayIterator that iterates through all connections
doctrine's avatar
doctrine committed
262 263 264 265
     *
     * @return ArrayIterator
     */
    public function getIterator() {
266
        return new ArrayIterator($this->connections);
doctrine's avatar
doctrine committed
267 268
    }
    /**
269 270
     * getCurrentConnection
     * returns the current connection
doctrine's avatar
doctrine committed
271
     *
zYne's avatar
zYne committed
272 273
     * @throws Doctrine_Connection_Exception       if there are no open connections
     * @return Doctrine_Connection
doctrine's avatar
doctrine committed
274
     */
275
    public function getCurrentConnection() {
doctrine's avatar
doctrine committed
276
        $i = $this->currIndex;
277
        if( ! isset($this->connections[$i]))
zYne's avatar
zYne committed
278
            throw new Doctrine_Connection_Exception();
doctrine's avatar
doctrine committed
279

280
        return $this->connections[$i];
doctrine's avatar
doctrine committed
281
    }
282
    public function getCurrentSession() { return $this->getCurrentConnection(); }
doctrine's avatar
doctrine committed
283 284 285 286 287 288 289 290 291
    /**
     * __toString
     * returns a string representation of this object
     *
     * @return string
     */
    public function __toString() {
        $r[] = "<pre>";
        $r[] = "Doctrine_Manager";
zYne's avatar
zYne committed
292
        $r[] = "Connections : ".count($this->connections);
doctrine's avatar
doctrine committed
293 294 295 296
        $r[] = "</pre>";
        return implode("\n",$r);
    }
}
297