| [ Index ] |
|
Code source de Symfony 1.0.0 |
1 <?php 2 3 /* 4 * $Id: Propel.php 110 2005-06-08 16:59:32Z hans $ 5 * 6 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 7 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 8 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 9 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 10 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 11 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 12 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 13 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 14 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 15 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 16 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 17 * 18 * This software consists of voluntary contributions made by many individuals 19 * and is licensed under the LGPL. For more information please see 20 * <http://propel.phpdb.org>. 21 */ 22 23 include_once 'propel/PropelException.php'; 24 include_once 'propel/adapter/DBAdapter.php'; 25 26 /** 27 * Propel's main resource pool and initialization & configuration class. 28 * 29 * This static class is used to handle Propel initialization and to maintain all of the 30 * open database connections and instantiated database maps. 31 * 32 * @author Hans Lellelid <hans@xmpl.rg> (Propel) 33 * @author Daniel Rall <dlr@finemaltcoding.com> (Torque) 34 * @author Magnús Þór Torfason <magnus@handtolvur.is> (Torque) 35 * @author Jason van Zyl <jvanzyl@apache.org> (Torque) 36 * @author Rafal Krzewski <Rafal.Krzewski@e-point.pl> (Torque) 37 * @author Martin Poeschl <mpoeschl@marmot.at> (Torque) 38 * @author Henning P. Schmiedehausen <hps@intermeta.de> (Torque) 39 * @author Kurt Schrader <kschrader@karmalab.org> (Torque) 40 * @version $Revision: 110 $ 41 * @package propel 42 */ 43 class Propel { 44 45 /** 46 * A constant for <code>default</code>. 47 */ 48 const DEFAULT_NAME = "default"; 49 50 /** 51 * A constant defining 'System is unusuable' logging level 52 */ 53 const LOG_EMERG = 0; 54 55 /** 56 * A constant defining 'Immediate action required' logging level 57 */ 58 const LOG_ALERT = 1; 59 60 /** 61 * A constant defining 'Critical conditions' logging level 62 */ 63 const LOG_CRIT = 2; 64 65 /** 66 * A constant defining 'Error conditions' logging level 67 */ 68 const LOG_ERR = 3; 69 70 /** 71 * A constant defining 'Warning conditions' logging level 72 */ 73 const LOG_WARNING = 4; 74 75 /** 76 * A constant defining 'Normal but significant' logging level 77 */ 78 const LOG_NOTICE = 5; 79 80 /** 81 * A constant defining 'Informational' logging level 82 */ 83 const LOG_INFO = 6; 84 85 /** 86 * A constant defining 'Debug-level messages' logging level 87 */ 88 const LOG_DEBUG = 7; 89 90 /** 91 * The db name that is specified as the default in the property file 92 */ 93 private static $defaultDBName; 94 95 /** 96 * The global cache of database maps 97 */ 98 private static $dbMaps = array(); 99 100 /** 101 * The cache of DB adapter keys 102 */ 103 private static $adapterMap; 104 105 /** 106 * The logging category. 107 */ 108 private static $category; 109 110 /** 111 * Propel-specific configuration. 112 */ 113 private static $configuration; 114 115 /** 116 * flag to set to true once this class has been initialized 117 */ 118 private static $isInit = false; 119 120 /** 121 * @var Log 122 */ 123 private static $logger = null; 124 125 /** 126 * Store mapbuilder classnames for peers that have been referenced prior 127 * to Propel being initialized. This can happen if the OM Peer classes are 128 * included before the Propel::init() method has been called. 129 */ 130 private static $mapBuilders = array(); 131 132 /** 133 * Cache of established connections (to eliminate overhead). 134 * @var array 135 */ 136 private static $connectionMap = array(); 137 138 /** 139 * initialize Propel 140 * @return void 141 * @throws PropelException Any exceptions caught during processing will be 142 * rethrown wrapped into a PropelException. 143 */ 144 public static function initialize() { 145 146 if (self::$configuration === null) { 147 throw new PropelException("Propel cannot be initialized without " 148 . "a valid configuration. Please check the log files " 149 . "for further details."); 150 } 151 152 self::configureLogging(); 153 154 // Now that we have dealt with processing the log properties 155 // that may be contained in the configuration we will make the 156 // configuration consist only of the remaining propel-specific 157 // properties that are contained in the configuration. First 158 // look for properties that are in the "propel" namespace. 159 $originalConf = self::$configuration; 160 self::$configuration = isset(self::$configuration['propel']) ? self::$configuration['propel'] : null; 161 162 if (empty(self::$configuration)) { 163 // Assume the original configuration already had any 164 // prefixes stripped. 165 self::$configuration = $originalConf; 166 } 167 168 // reset the connection map (this should enable runtime changes of connection params) 169 self::$connectionMap = array(); 170 171 self::initAdapters(self::$configuration); 172 173 self::$isInit = true; 174 175 // map builders may be registered w/ Propel before Propel has 176 // been initialized; in this case they are stored in a static 177 // var of this class & now can be propertly initialized. 178 foreach(self::$mapBuilders as $mbClass) { 179 BasePeer::getMapBuilder($mbClass); 180 } 181 182 // now that the pre-loaded map builders have been propertly initialized 183 // empty the array. 184 // any further mapBuilders will be build by the generated MapBuilder classes. 185 self::$mapBuilders = array(); 186 } 187 188 /** 189 * Setup the adapters needed. An adapter must be defined for each database connection. 190 * Generally the adapter will be the same as the PEAR phpname; e.g. for MySQL, use the 191 * 'mysql' adapter. 192 * @param array $configuration the Configuration representing the properties file 193 * @throws PropelException Any exceptions caught during processing will be 194 * rethrown wrapped into a PropelException. 195 */ 196 private static function initAdapters($configuration) { 197 198 self::$adapterMap = array(); 199 200 $c = isset($configuration['datasources']) ? $configuration['datasources'] : null; 201 202 if (!empty($c)) { 203 try { 204 foreach($c as $handle => $properties) { 205 if (is_array($properties) && isset($properties['adapter'])) { 206 $db = DBAdapter::factory($properties['adapter']); 207 // register the adapter for this name 208 self::$adapterMap[$handle] = $db; 209 } 210 } 211 } catch (Exception $e) { 212 throw new PropelException("Unable to initialize adapters.", $e); 213 } 214 } else { 215 self::log("There were no adapters in the configuration.", self::LOG_WARNING); 216 } 217 } 218 219 /** 220 * configure propel 221 * 222 * @param string $config Path (absolute or relative to include_path) to config file. 223 * @return void 224 * @throws PropelException If configuration file cannot be opened. (E_WARNING probably will also be raised in PHP) 225 */ 226 public static function configure($configFile) 227 { 228 self::$configuration = include($configFile); 229 if (self::$configuration === false) { 230 throw new PropelException("Unable to open configuration file: " . var_export($configFile, true)); 231 } 232 } 233 234 /** 235 * Initialization of Propel with a properties file. 236 * 237 * @param string $c The Propel configuration file path. 238 * @return void 239 * @throws PropelException Any exceptions caught during processing will be 240 * rethrown wrapped into a PropelException. 241 */ 242 public static function init($c) 243 { 244 self::configure($c); 245 self::initialize(); 246 } 247 248 /** 249 * Determine whether Propel has already been initialized. 250 * 251 * @return boolean True if Propel is already initialized. 252 */ 253 public static function isInit() 254 { 255 return self::$isInit; 256 } 257 258 /** 259 * Sets the configuration for Propel and all dependencies. 260 * 261 * @param array $c the Configuration 262 * @return void 263 */ 264 public static function setConfiguration($c) 265 { 266 self::$configuration = $c; 267 } 268 269 /** 270 * Get the configuration for this component. 271 * 272 * @return the Configuration 273 */ 274 public static function getConfiguration() 275 { 276 return self::$configuration; 277 } 278 279 /** 280 * Configure the logging for this subsystem. 281 * The logging system is only configured if there is a 'log' 282 * section in the passed-in runtime configuration. 283 * @return void 284 */ 285 protected static function configureLogging() { 286 if (self::$logger === null) { 287 if (isset(self::$configuration['log']) && is_array(self::$configuration['log']) && count(self::$configuration['log'])) { 288 include_once 'Log.php'; // PEAR Log class 289 $c = self::$configuration['log']; 290 // array casting handles bug in PHP5b2 where the isset() checks 291 // below may return true if $c is not an array (e.g. is a string) 292 293 $type = isset($c['type']) ? $c['type'] : 'file'; 294 $name = isset($c['name']) ? $c['name'] : './propel.log'; 295 $ident = isset($c['ident']) ? $c['ident'] : 'propel'; 296 $conf = isset($c['conf']) ? $c['conf'] : array(); 297 $level = isset($c['level']) ? $c['level'] : PEAR_LOG_DEBUG; 298 299 self::$logger = Log::singleton($type, $name, $ident, $conf, $level); 300 } // if isset() 301 } 302 } 303 304 /** 305 * Override the configured logger. 306 * 307 * This is primarily for things like unit tests / debugging where 308 * you want to change the logger without altering the configuration file. 309 * 310 * You can use any logger class that implements the propel.logger.BasicLogger 311 * interface. This interface is based on PEAR::Log, so you can also simply pass 312 * a PEAR::Log object to this method. 313 * 314 * @param object $logger The new logger to use. ([PEAR] Log or BasicLogger) 315 * @return void 316 */ 317 public static function setLogger($logger) 318 { 319 self::$logger = $logger; 320 } 321 322 /** 323 * Returns true if a logger, for example PEAR::Log, has been configured, 324 * otherwise false. 325 * 326 * @return boolean True if Propel uses logging 327 */ 328 public static function hasLogger() 329 { 330 return self::$logger !== null; 331 } 332 333 /** 334 * Get the configured logger. 335 * @return object Configured log class ([PEAR] Log or BasicLogger). 336 */ 337 public static function logger() 338 { 339 return self::$logger; 340 } 341 342 /** 343 * Logs a message 344 * If a logger has been configured, the logger will be used, otherwrise the 345 * logging message will be discarded without any further action 346 * 347 * @param string $message The message that will be logged. 348 * @param string $level The logging level. 349 * @return boolean True if the message was logged successfully or no logger was used. 350 */ 351 public static function log($message, $level = self::LOG_DEBUG) 352 { 353 if(self::hasLogger()) 354 { 355 $logger = self::logger(); 356 switch($level) 357 { 358 case self::LOG_EMERG: 359 return $logger->log($message, $level); 360 case self::LOG_ALERT: 361 return $logger->alert($message); 362 case self::LOG_CRIT: 363 return $logger->crit($message); 364 case self::LOG_ERR: 365 return $logger->err($message); 366 case self::LOG_WARNING: 367 return $logger->warning($message); 368 case self::LOG_NOTICE: 369 return $logger->notice($message); 370 case self::LOG_INFO: 371 return $logger->info($message); 372 default: 373 return $logger->debug($message); 374 } 375 } 376 return true; 377 } 378 379 /** 380 * Returns the database map information. Name relates to the name 381 * of the connection pool to associate with the map. 382 * 383 * The database maps are "registered" by the generated map builder classes. 384 * 385 * @param string $name The name of the database corresponding to the DatabaseMapto retrieve. 386 * @return DatabaseMap The named <code>DatabaseMap</code>. 387 * @throws PropelException - if database map is null or propel was not initialized properly. 388 */ 389 public static function getDatabaseMap($name = null) { 390 391 if ($name === null) { 392 $name = self::getDefaultDB(); 393 if ($name === null) { 394 throw new PropelException("DatabaseMap name was null!"); 395 } 396 } 397 398 // CACHEHOOK - this would be a good place 399 // to add shared memory caching options (database 400 // maps should be a pretty safe candidate for shared mem caching) 401 402 if (isset(self::$dbMaps[$name])) { 403 $map = self::$dbMaps[$name]; 404 } else { 405 $map = self::initDatabaseMap($name); 406 } 407 408 return $map; 409 } 410 411 /** 412 * Creates and initializes the mape for the named database. 413 * 414 * The database maps are "registered" by the generated map builder classes 415 * by calling this method and then adding the tables, etc. to teh DatabaseMap 416 * object returned from this method. 417 * 418 * @param string $name The name of the database to map. 419 * @return DatabaseMap The desired map. 420 * @throws PropelException Any exceptions caught during processing will be 421 * rethrown wrapped into a PropelException. 422 */ 423 private static function initDatabaseMap($name) 424 { 425 $map = new DatabaseMap($name); 426 self::$dbMaps[$name] = $map; 427 return $map; 428 } 429 430 /** 431 * Register a MapBuilder 432 * 433 * @param string $className the MapBuilder 434 */ 435 public static function registerMapBuilder($className) 436 { 437 self::$mapBuilders[] = $className; 438 } 439 440 /** 441 * Returns the specified property of the given database, or the empty 442 * string if no value is set for the property. 443 * 444 * @param string $db The name of the database whose property to get. 445 * @param string $prop The name of the property to get. 446 * @return mixed The property's value. 447 */ 448 private static function getDatabaseProperty($db, $prop) 449 { 450 return isset(self::$configuration['datasources'][$db][$prop]) ? self::$configuration['datasources'][$db][$prop] : null; 451 } 452 453 /** 454 * 455 * @param string $name The database name. 456 * @return Connection A database connection 457 * @throws PropelException - if no conneciton params, or SQLException caught when trying to connect. 458 */ 459 public static function getConnection($name = null) { 460 461 if ($name === null) { 462 $name = self::getDefaultDB(); 463 } 464 465 $con = isset(self::$connectionMap[$name]) ? self::$connectionMap[$name] : null; 466 467 if ($con === null) { 468 469 $dsn = isset(self::$configuration['datasources'][$name]['connection']) ? self::$configuration['datasources'][$name]['connection'] : null; 470 if ($dsn === null) { 471 throw new PropelException("No connection params set for " . $name); 472 } 473 474 include_once 'creole/Creole.php'; 475 476 // if specified, use custom driver 477 if (isset(self::$configuration['datasources'][$name]['driver'])) { 478 Creole::registerDriver($dsn['phptype'], self::$configuration['datasources'][$name]['driver']); 479 } 480 481 try { 482 $con = Creole::getConnection($dsn); 483 } catch (SQLException $e) { 484 throw new PropelException($e); 485 } 486 self::$connectionMap[$name] = $con; 487 } 488 489 return $con; 490 } 491 492 /** 493 * Returns database adapter for a specific connection pool. 494 * 495 * @param string $name A database name. 496 * @return DBAdapter The corresponding database adapter. 497 * @throws PropelException - if unable to find DBdapter for specified db. 498 */ 499 public static function getDB($name = null) 500 { 501 if ($name === null) { 502 $name = self::getDefaultDB(); 503 } 504 if (!isset(self::$adapterMap[$name])) { 505 throw new PropelException("Unable to load DBAdapter for database '" . var_export($name, true) . "' (check your runtime properties file!)"); 506 } 507 return self::$adapterMap[$name]; 508 } 509 510 /** 511 * Returns the name of the default database. 512 * 513 * @return string Name of the default DB 514 */ 515 public static function getDefaultDB() 516 { 517 if (self::$configuration === null) { 518 return self::DEFAULT_NAME; 519 } elseif (self::$defaultDBName === null) { 520 // Determine default database name. 521 self::$defaultDBName = isset(self::$configuration['datasources']['default']) ? self::$configuration['datasources']['default'] : self::DEFAULT_NAME; 522 } 523 return self::$defaultDBName; 524 } 525 526 /** 527 * Include once a file specified in DOT notation and reutrn unqualified clasname. 528 * 529 * Package notation is expected to be relative to a location 530 * on the PHP include_path. The dot-path classes are used as a way 531 * to represent both classname and filesystem location; there is 532 * an inherent assumption about filenaming. To get around these 533 * naming requirements you can include the class yourself 534 * and then just use the classname instead of dot-path. 535 * 536 * @param string $class dot-path to clas (e.g. path.to.my.ClassName). 537 * @return string unqualified classname 538 */ 539 public static function import($path) { 540 541 // extract classname 542 if (($pos = strrpos($path, '.')) === false) { 543 $class = $path; 544 } else { 545 $class = substr($path, $pos + 1); 546 } 547 548 // check if class exists 549 if (class_exists($class, false)) { 550 return $class; 551 } 552 553 // turn to filesystem path 554 $path = strtr($path, '.', DIRECTORY_SEPARATOR) . '.php'; 555 556 // include class 557 $ret = include_once($path); 558 if ($ret === false) { 559 throw new PropelException("Unable to import class: " . $class . " from " . $path); 560 } 561 562 // return qualified name 563 return $class; 564 } 565 566 /** 567 * Closes any associated resource handles. 568 * 569 * This method frees any database connection handles that have been 570 * opened by the getConnection() method. 571 * 572 * @return void 573 */ 574 public static function close() 575 { 576 foreach(self::$connectionMap as $conn) { 577 $conn->close(); 578 } 579 } 580 581 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Fri Mar 16 22:42:14 2007 | par Balluche grâce à PHPXref 0.7 |