Spaces:
Sleeping
Sleeping
| /* | |
| * $Id: Propel.php 601 2007-03-07 13:23:12Z hans $ | |
| * | |
| * 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 please see | |
| * <http://propel.phpdb.org>. | |
| */ | |
| include_once 'propel/PropelException.php'; | |
| include_once 'adapter/DBAdapter.php'; | |
| /** | |
| * Propel's main resource pool and initialization & configuration class. | |
| * | |
| * This static class is used to handle Propel initialization and to maintain all of the | |
| * open database connections and instantiated database maps. | |
| * | |
| * @author Hans Lellelid <hans@xmpl.rg> (Propel) | |
| * @author Daniel Rall <dlr@finemaltcoding.com> (Torque) | |
| * @author Magn�s ��r Torfason <magnus@handtolvur.is> (Torque) | |
| * @author Jason van Zyl <jvanzyl@apache.org> (Torque) | |
| * @author Rafal Krzewski <Rafal.Krzewski@e-point.pl> (Torque) | |
| * @author Martin Poeschl <mpoeschl@marmot.at> (Torque) | |
| * @author Henning P. Schmiedehausen <hps@intermeta.de> (Torque) | |
| * @author Kurt Schrader <kschrader@karmalab.org> (Torque) | |
| * @version $Revision: 601 $ | |
| * @package propel | |
| */ | |
| class Propel { | |
| /** | |
| * A constant for <code>default</code>. | |
| */ | |
| const DEFAULT_NAME = "default"; | |
| /** | |
| * A constant defining 'System is unusuable' logging level | |
| */ | |
| const LOG_EMERG = 0; | |
| /** | |
| * A constant defining 'Immediate action required' logging level | |
| */ | |
| const LOG_ALERT = 1; | |
| /** | |
| * A constant defining 'Critical conditions' logging level | |
| */ | |
| const LOG_CRIT = 2; | |
| /** | |
| * A constant defining 'Error conditions' logging level | |
| */ | |
| const LOG_ERR = 3; | |
| /** | |
| * A constant defining 'Warning conditions' logging level | |
| */ | |
| const LOG_WARNING = 4; | |
| /** | |
| * A constant defining 'Normal but significant' logging level | |
| */ | |
| const LOG_NOTICE = 5; | |
| /** | |
| * A constant defining 'Informational' logging level | |
| */ | |
| const LOG_INFO = 6; | |
| /** | |
| * A constant defining 'Debug-level messages' logging level | |
| */ | |
| const LOG_DEBUG = 7; | |
| /** | |
| * The Propel version. | |
| */ | |
| const VERSION = '1.2.1'; | |
| /** | |
| * The db name that is specified as the default in the property file | |
| */ | |
| private static $defaultDBName; | |
| /** | |
| * The global cache of database maps | |
| */ | |
| private static $dbMaps = array(); | |
| /** | |
| * The cache of DB adapter keys | |
| */ | |
| private static $adapterMap; | |
| /** | |
| * The logging category. | |
| */ | |
| private static $category; | |
| /** | |
| * Propel-specific configuration. | |
| */ | |
| private static $configuration; | |
| /** | |
| * flag to set to true once this class has been initialized | |
| */ | |
| private static $isInit = false; | |
| /** | |
| * @var Log | |
| */ | |
| private static $logger = null; | |
| /** | |
| * Store mapbuilder classnames for peers that have been referenced prior | |
| * to Propel being initialized. This can happen if the OM Peer classes are | |
| * included before the Propel::init() method has been called. | |
| */ | |
| private static $mapBuilders = array(); | |
| /** | |
| * Cache of established connections (to eliminate overhead). | |
| * @var array | |
| */ | |
| private static $connectionMap = array(); | |
| /** | |
| * initialize Propel | |
| * @return void | |
| * @throws PropelException Any exceptions caught during processing will be | |
| * rethrown wrapped into a PropelException. | |
| */ | |
| public static function initialize() { | |
| if (self::$configuration === null) { | |
| throw new PropelException("Propel cannot be initialized without " | |
| . "a valid configuration. Please check the log files " | |
| . "for further details."); | |
| } | |
| self::configureLogging(); | |
| // Now that we have dealt with processing the log properties | |
| // that may be contained in the configuration we will make the | |
| // configuration consist only of the remaining propel-specific | |
| // properties that are contained in the configuration. First | |
| // look for properties that are in the "propel" namespace. | |
| $originalConf = self::$configuration; | |
| self::$configuration = isset(self::$configuration['propel']) ? self::$configuration['propel'] : null; | |
| if (empty(self::$configuration)) { | |
| // Assume the original configuration already had any | |
| // prefixes stripped. | |
| self::$configuration = $originalConf; | |
| } | |
| // reset the connection map (this should enable runtime changes of connection params) | |
| self::$connectionMap = array(); | |
| self::initAdapters(self::$configuration); | |
| self::$isInit = true; | |
| // map builders may be registered w/ Propel before Propel has | |
| // been initialized; in this case they are stored in a static | |
| // var of this class & now can be propertly initialized. | |
| foreach(self::$mapBuilders as $mbClass) { | |
| BasePeer::getMapBuilder($mbClass); | |
| } | |
| // now that the pre-loaded map builders have been propertly initialized | |
| // empty the array. | |
| // any further mapBuilders will be build by the generated MapBuilder classes. | |
| self::$mapBuilders = array(); | |
| } | |
| /** | |
| * Setup the adapters needed. An adapter must be defined for each database connection. | |
| * Generally the adapter will be the same as the PEAR phpname; e.g. for MySQL, use the | |
| * 'mysql' adapter. | |
| * @param array $configuration the Configuration representing the properties file | |
| * @throws PropelException Any exceptions caught during processing will be | |
| * rethrown wrapped into a PropelException. | |
| */ | |
| private static function initAdapters($configuration) { | |
| self::$adapterMap = array(); | |
| $c = isset($configuration['datasources']) ? $configuration['datasources'] : null; | |
| if (!empty($c)) { | |
| try { | |
| foreach($c as $handle => $properties) { | |
| if (is_array($properties) && isset($properties['adapter'])) { | |
| $db = DBAdapter::factory($properties['adapter']); | |
| // register the adapter for this name | |
| self::$adapterMap[$handle] = $db; | |
| } | |
| } | |
| } catch (Exception $e) { | |
| throw new PropelException("Unable to initialize adapters.", $e); | |
| } | |
| } else { | |
| self::log("There were no adapters in the configuration.", self::LOG_WARNING); | |
| } | |
| } | |
| /** | |
| * configure propel | |
| * | |
| * @param string $config Path (absolute or relative to include_path) to config file. | |
| * @return void | |
| * @throws PropelException If configuration file cannot be opened. (E_WARNING probably will also be raised in PHP) | |
| */ | |
| public static function krumo() | |
| { | |
| krumo ( self::$configuration); | |
| } | |
| public static function configure($configFile) | |
| { | |
| self::$configuration = include($configFile); | |
| if (self::$configuration === false) { | |
| throw new PropelException("Unable to open configuration file: " . var_export($configFile, true)); | |
| } | |
| //include($configFile ); | |
| } | |
| /** | |
| * Initialization of Propel with a properties file. | |
| * | |
| * @param string $c The Propel configuration file path. | |
| * @return void | |
| * @throws PropelException Any exceptions caught during processing will be | |
| * rethrown wrapped into a PropelException. | |
| */ | |
| public static function init($c) | |
| { | |
| self::configure($c); | |
| self::initialize(); | |
| } | |
| public static function initConfiguration($configuration) | |
| { | |
| self::$configuration = $configuration; | |
| self::initialize(); | |
| } | |
| /** | |
| * Determine whether Propel has already been initialized. | |
| * | |
| * @return boolean True if Propel is already initialized. | |
| */ | |
| public static function isInit() | |
| { | |
| return self::$isInit; | |
| } | |
| /** | |
| * Sets the configuration for Propel and all dependencies. | |
| * | |
| * @param array $c the Configuration | |
| * @return void | |
| */ | |
| public static function setConfiguration($c) | |
| { | |
| self::$configuration = $c; | |
| } | |
| /** | |
| * Get the configuration for this component. | |
| * | |
| * @return the Configuration | |
| */ | |
| public static function getConfiguration() | |
| { | |
| return self::$configuration; | |
| } | |
| /** | |
| * Configure the logging for this subsystem. | |
| * The logging system is only configured if there is a 'log' | |
| * section in the passed-in runtime configuration. | |
| * @return void | |
| */ | |
| protected static function configureLogging() { | |
| if (self::$logger === null) { | |
| if (isset(self::$configuration['log']) && is_array(self::$configuration['log']) && count(self::$configuration['log'])) { | |
| include_once 'Log.php'; // PEAR Log class | |
| $c = self::$configuration['log']; | |
| // array casting handles bug in PHP5b2 where the isset() checks | |
| // below may return true if $c is not an array (e.g. is a string) | |
| $type = isset($c['type']) ? $c['type'] : 'file'; | |
| $name = isset($c['name']) ? $c['name'] : './propel.log'; | |
| $ident = isset($c['ident']) ? $c['ident'] : 'propel'; | |
| $conf = isset($c['conf']) ? $c['conf'] : array(); | |
| $level = isset($c['level']) ? $c['level'] : PEAR_LOG_DEBUG; | |
| self::$logger = Log::singleton($type, $name, $ident, $conf, $level); | |
| } // if isset() | |
| } | |
| } | |
| /** | |
| * Override the configured logger. | |
| * | |
| * This is primarily for things like unit tests / debugging where | |
| * you want to change the logger without altering the configuration file. | |
| * | |
| * You can use any logger class that implements the propel.logger.BasicLogger | |
| * interface. This interface is based on PEAR::Log, so you can also simply pass | |
| * a PEAR::Log object to this method. | |
| * | |
| * @param object $logger The new logger to use. ([PEAR] Log or BasicLogger) | |
| * @return void | |
| */ | |
| public static function setLogger($logger) | |
| { | |
| self::$logger = $logger; | |
| } | |
| /** | |
| * Returns true if a logger, for example PEAR::Log, has been configured, | |
| * otherwise false. | |
| * | |
| * @return boolean True if Propel uses logging | |
| */ | |
| public static function hasLogger() | |
| { | |
| return self::$logger !== null; | |
| } | |
| /** | |
| * Get the configured logger. | |
| * @return object Configured log class ([PEAR] Log or BasicLogger). | |
| */ | |
| public static function logger() | |
| { | |
| return self::$logger; | |
| } | |
| /** | |
| * Logs a message | |
| * If a logger has been configured, the logger will be used, otherwrise the | |
| * logging message will be discarded without any further action | |
| * | |
| * @param string $message The message that will be logged. | |
| * @param string $level The logging level. | |
| * @return boolean True if the message was logged successfully or no logger was used. | |
| */ | |
| public static function log($message, $level = self::LOG_DEBUG) | |
| { | |
| if(self::hasLogger()) | |
| { | |
| $logger = self::logger(); | |
| switch($level) | |
| { | |
| case self::LOG_EMERG: | |
| return $logger->log($message, $level); | |
| case self::LOG_ALERT: | |
| return $logger->alert($message); | |
| case self::LOG_CRIT: | |
| return $logger->crit($message); | |
| case self::LOG_ERR: | |
| return $logger->err($message); | |
| case self::LOG_WARNING: | |
| return $logger->warning($message); | |
| case self::LOG_NOTICE: | |
| return $logger->notice($message); | |
| case self::LOG_INFO: | |
| return $logger->info($message); | |
| default: | |
| return $logger->debug($message); | |
| } | |
| } | |
| return true; | |
| } | |
| /** | |
| * Returns the database map information. Name relates to the name | |
| * of the connection pool to associate with the map. | |
| * | |
| * The database maps are "registered" by the generated map builder classes. | |
| * | |
| * @param string $name The name of the database corresponding to the DatabaseMapto retrieve. | |
| * @return DatabaseMap The named <code>DatabaseMap</code>. | |
| * @throws PropelException - if database map is null or propel was not initialized properly. | |
| */ | |
| public static function getDatabaseMap($name = null) { | |
| if ($name === null) { | |
| $name = self::getDefaultDB(); | |
| if ($name === null) { | |
| throw new PropelException("DatabaseMap name was null!"); | |
| } | |
| } | |
| // CACHEHOOK - this would be a good place | |
| // to add shared memory caching options (database | |
| // maps should be a pretty safe candidate for shared mem caching) | |
| if (isset(self::$dbMaps[$name])) { | |
| $map = self::$dbMaps[$name]; | |
| } else { | |
| $map = self::initDatabaseMap($name); | |
| } | |
| return $map; | |
| } | |
| /** | |
| * Creates and initializes the mape for the named database. | |
| * | |
| * The database maps are "registered" by the generated map builder classes | |
| * by calling this method and then adding the tables, etc. to teh DatabaseMap | |
| * object returned from this method. | |
| * | |
| * @param string $name The name of the database to map. | |
| * @return DatabaseMap The desired map. | |
| * @throws PropelException Any exceptions caught during processing will be | |
| * rethrown wrapped into a PropelException. | |
| */ | |
| private static function initDatabaseMap($name) | |
| { | |
| $map = new DatabaseMap($name); | |
| self::$dbMaps[$name] = $map; | |
| return $map; | |
| } | |
| /** | |
| * Register a MapBuilder | |
| * | |
| * @param string $className the MapBuilder | |
| */ | |
| public static function registerMapBuilder($className) | |
| { | |
| self::$mapBuilders[] = $className; | |
| } | |
| /** | |
| * Returns the specified property of the given database, or the empty | |
| * string if no value is set for the property. | |
| * | |
| * @param string $db The name of the database whose property to get. | |
| * @param string $prop The name of the property to get. | |
| * @return mixed The property's value. | |
| */ | |
| private static function getDatabaseProperty($db, $prop) | |
| { | |
| return isset(self::$configuration['datasources'][$db][$prop]) ? self::$configuration['datasources'][$db][$prop] : null; | |
| } | |
| /** | |
| * | |
| * @param string $name The database name. | |
| * @return Connection A database connection | |
| * @throws PropelException - if no conneciton params, or SQLException caught when trying to connect. | |
| */ | |
| public static function getConnection($name = null) { | |
| if ($name === null) { | |
| $name = self::getDefaultDB(); | |
| } | |
| $con = isset(self::$connectionMap[$name]) ? self::$connectionMap[$name] : null; | |
| if ($con === null || $name === 'dbarray') { | |
| $dsn = isset(self::$configuration['datasources'][$name]['connection']) ? self::$configuration['datasources'][$name]['connection'] : null; | |
| if ($dsn === null) { | |
| if(isset($_SESSION['PROCESS'])) { | |
| /** Added By Erik Amaru <erik@colosa.com ******************************* | |
| * @date: 27-05-08 11:48 * | |
| * @Description: this was added for the additional database connections * | |
| ***********************************************************************/ | |
| $oDbConnections = new DbConnections($_SESSION['PROCESS']); | |
| $oDbConnections->loadAdditionalConnections(); | |
| $dsn = isset(self::$configuration['datasources'][$name]['connection']) ? self::$configuration['datasources'][$name]['connection'] : null; | |
| } else { | |
| throw new PropelException("No connection params set for " . $name); | |
| } | |
| } | |
| // if specified, use custom driver | |
| if (isset(self::$configuration['datasources'][$name]['driver'])) { | |
| Creole::registerDriver($dsn['phptype'], self::$configuration['datasources'][$name]['driver']); | |
| } | |
| try { | |
| $con = Creole::getConnection($dsn); | |
| } catch (SQLException $e) { | |
| throw new PropelException($e); | |
| } | |
| self::$connectionMap[$name] = $con; | |
| } | |
| return $con; | |
| } | |
| /** | |
| * Returns database adapter for a specific connection pool. | |
| * | |
| * @param string $name A database name. | |
| * @return DBAdapter The corresponding database adapter. | |
| * @throws PropelException - if unable to find DBdapter for specified db. | |
| */ | |
| public static function getDB($name = null) | |
| { | |
| if ($name === null) { | |
| $name = self::getDefaultDB(); | |
| } | |
| if (!isset(self::$adapterMap[$name])) { | |
| //throw new PropelException("Unable to load DBAdapter for database '" . var_export($name, true) . "' (check your runtime properties file!)"); | |
| throw new PropelException("Unable to load DBAdapter for database '' (check your runtime properties file!)"); | |
| } | |
| return self::$adapterMap[$name]; | |
| } | |
| /** | |
| * Returns the name of the default database. | |
| * | |
| * @return string Name of the default DB | |
| */ | |
| public static function getDefaultDB() | |
| { | |
| if (self::$configuration === null) { | |
| return self::DEFAULT_NAME; | |
| } elseif (self::$defaultDBName === null) { | |
| // Determine default database name. | |
| self::$defaultDBName = isset(self::$configuration['datasources']['default']) ? self::$configuration['datasources']['default'] : self::DEFAULT_NAME; | |
| } | |
| return self::$defaultDBName; | |
| } | |
| /** | |
| * Include once a file specified in DOT notation and reutrn unqualified clasname. | |
| * | |
| * Package notation is expected to be relative to a location | |
| * on the PHP include_path. The dot-path classes are used as a way | |
| * to represent both classname and filesystem location; there is | |
| * an inherent assumption about filenaming. To get around these | |
| * naming requirements you can include the class yourself | |
| * and then just use the classname instead of dot-path. | |
| * | |
| * @param string $class dot-path to clas (e.g. path.to.my.ClassName). | |
| * @return string unqualified classname | |
| */ | |
| public static function import($path) { | |
| // extract classname | |
| if (($pos = strrpos($path, '.')) === false) { | |
| $class = $path; | |
| } else { | |
| $class = substr($path, $pos + 1); | |
| } | |
| // check if class exists | |
| if (class_exists($class, false)) { | |
| return $class; | |
| } | |
| // turn to filesystem path | |
| $path = strtr($path, '.', DIRECTORY_SEPARATOR) . '.php'; | |
| // include class | |
| $ret = include_once($path); | |
| if ($ret === false) { | |
| throw new PropelException("Unable to import class: " . $class . " from " . $path); | |
| } | |
| // return qualified name | |
| return $class; | |
| } | |
| /** | |
| * Closes any associated resource handles. | |
| * | |
| * This method frees any database connection handles that have been | |
| * opened by the getConnection() method. | |
| * | |
| * @return void | |
| */ | |
| public static function close() | |
| { | |
| $lastQuery = ""; | |
| foreach (self::$connectionMap as $cnn) { | |
| if (get_class($cnn) != "DBArrayConnection") { | |
| if(isset($cnn->lastQuery)){ | |
| if (gettype($cnn->getResource()) == "resource" && $cnn->isConnected() && $cnn->lastQuery != $lastQuery) { | |
| $cnn->close(); | |
| } | |
| $lastQuery = $cnn->lastQuery; | |
| } | |
| } | |
| } | |
| } | |
| /** | |
| * @param $name string The connection name | |
| * @return Connection A database connection | |
| * @throws PropelException | |
| */ | |
| public static function getDbConnection($name) | |
| { | |
| /*----------------------------------********---------------------------------*/ | |
| return null; | |
| /*----------------------------------********---------------------------------*/ | |
| if (! empty(self::$configuration['datasources'][$name]['connection'])) { | |
| return self::getConnection($name); | |
| } | |
| // the connection names always should be have a underscore like: workflow_ro, rbac_rw | |
| // on fallback, we will try found a connection named: "workflow" if "workflow_ro" does not exist. | |
| // the name without the "_ro" part. | |
| $defaultDbName = substr($name, 0, strrpos($name, '_')); | |
| if (! empty(self::$configuration['datasources'][$defaultDbName]['connection'])) { | |
| return self::getConnection($defaultDbName); | |
| } | |
| throw new PropelException('Error, database connection named "'.$name.'" is not defined for Propel.'); | |
| } | |
| } | |