adding zend project folders into old campcaster.
This commit is contained in:
parent
56abfaf28e
commit
7ef0c18b26
4045 changed files with 1054952 additions and 0 deletions
916
library/propel/runtime/lib/Propel.php
Normal file
916
library/propel/runtime/lib/Propel.php
Normal file
|
@ -0,0 +1,916 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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: 1811 $
|
||||
* @package propel.runtime
|
||||
*/
|
||||
class Propel
|
||||
{
|
||||
/**
|
||||
* The Propel version.
|
||||
*/
|
||||
const VERSION = '1.5.2';
|
||||
|
||||
/**
|
||||
* 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 class name for a PDO object.
|
||||
*/
|
||||
const CLASS_PDO = 'PDO';
|
||||
|
||||
/**
|
||||
* The class name for a PropelPDO object.
|
||||
*/
|
||||
const CLASS_PROPEL_PDO = 'PropelPDO';
|
||||
|
||||
/**
|
||||
* The class name for a DebugPDO object.
|
||||
*/
|
||||
const CLASS_DEBUG_PDO = 'DebugPDO';
|
||||
|
||||
/**
|
||||
* Constant used to request a READ connection (applies to replication).
|
||||
*/
|
||||
const CONNECTION_READ = 'read';
|
||||
|
||||
/**
|
||||
* Constant used to request a WRITE connection (applies to replication).
|
||||
*/
|
||||
const CONNECTION_WRITE = 'write';
|
||||
|
||||
/**
|
||||
* @var string The db name that is specified as the default in the property file
|
||||
*/
|
||||
private static $defaultDBName;
|
||||
|
||||
/**
|
||||
* @var array The global cache of database maps
|
||||
*/
|
||||
private static $dbMaps = array();
|
||||
|
||||
/**
|
||||
* @var array The cache of DB adapter keys
|
||||
*/
|
||||
private static $adapterMap = array();
|
||||
|
||||
/**
|
||||
* @var array Cache of established connections (to eliminate overhead).
|
||||
*/
|
||||
private static $connectionMap = array();
|
||||
|
||||
/**
|
||||
* @var PropelConfiguration Propel-specific configuration.
|
||||
*/
|
||||
private static $configuration;
|
||||
|
||||
/**
|
||||
* @var bool flag to set to true once this class has been initialized
|
||||
*/
|
||||
private static $isInit = false;
|
||||
|
||||
/**
|
||||
* @var Log optional logger
|
||||
*/
|
||||
private static $logger = null;
|
||||
|
||||
/**
|
||||
* @var string The name of the database mapper class
|
||||
*/
|
||||
private static $databaseMapClass = 'DatabaseMap';
|
||||
|
||||
/**
|
||||
* @var bool Whether the object instance pooling is enabled
|
||||
*/
|
||||
private static $instancePoolingEnabled = true;
|
||||
|
||||
/**
|
||||
* @var bool For replication, whether to force the use of master connection.
|
||||
*/
|
||||
private static $forceMasterConnection = false;
|
||||
|
||||
/**
|
||||
* @var string Base directory to use for autoloading. Initialized in self::initBaseDir()
|
||||
*/
|
||||
protected static $baseDir;
|
||||
|
||||
/**
|
||||
* @var array A map of class names and their file paths for autoloading
|
||||
*/
|
||||
protected static $autoloadMap = array(
|
||||
|
||||
'DBAdapter' => 'adapter/DBAdapter.php',
|
||||
'DBMSSQL' => 'adapter/DBMSSQL.php',
|
||||
'MssqlPropelPDO' => 'adapter/MSSQL/MssqlPropelPDO.php',
|
||||
'MssqlDebugPDO' => 'adapter/MSSQL/MssqlDebugPDO.php',
|
||||
'MssqlDateTime' => 'adapter/MSSQL/MssqlDateTime.class.php',
|
||||
'DBMySQL' => 'adapter/DBMySQL.php',
|
||||
'DBMySQLi' => 'adapter/DBMySQLi.php',
|
||||
'DBNone' => 'adapter/DBNone.php',
|
||||
'DBOracle' => 'adapter/DBOracle.php',
|
||||
'DBPostgres' => 'adapter/DBPostgres.php',
|
||||
'DBSQLite' => 'adapter/DBSQLite.php',
|
||||
'DBSybase' => 'adapter/DBSybase.php',
|
||||
|
||||
'PropelArrayCollection' => 'collection/PropelArrayCollection.php',
|
||||
'PropelCollection' => 'collection/PropelCollection.php',
|
||||
'PropelObjectCollection' => 'collection/PropelObjectCollection.php',
|
||||
'PropelOnDemandCollection' => 'collection/PropelOnDemandCollection.php',
|
||||
'PropelOnDemandIterator' => 'collection/PropelOnDemandIterator.php',
|
||||
|
||||
'PropelConfiguration' => 'config/PropelConfiguration.php',
|
||||
'PropelConfigurationIterator' => 'config/PropelConfigurationIterator.php',
|
||||
|
||||
'PropelPDO' => 'connection/PropelPDO.php',
|
||||
'DebugPDO' => 'connection/DebugPDO.php',
|
||||
'DebugPDOStatement' => 'connection/DebugPDOStatement.php',
|
||||
|
||||
'PropelException' => 'exception/PropelException.php',
|
||||
|
||||
'ModelWith' => 'formatter/ModelWith.php',
|
||||
'PropelArrayFormatter' => 'formatter/PropelArrayFormatter.php',
|
||||
'PropelFormatter' => 'formatter/PropelFormatter.php',
|
||||
'PropelObjectFormatter' => 'formatter/PropelObjectFormatter.php',
|
||||
'PropelOnDemandFormatter' => 'formatter/PropelOnDemandFormatter.php',
|
||||
'PropelStatementFormatter' => 'formatter/PropelStatementFormatter.php',
|
||||
|
||||
'BasicLogger' => 'logger/BasicLogger.php',
|
||||
'MojaviLogAdapter' => 'logger/MojaviLogAdapter.php',
|
||||
|
||||
'ColumnMap' => 'map/ColumnMap.php',
|
||||
'DatabaseMap' => 'map/DatabaseMap.php',
|
||||
'TableMap' => 'map/TableMap.php',
|
||||
'RelationMap' => 'map/RelationMap.php',
|
||||
'ValidatorMap' => 'map/ValidatorMap.php',
|
||||
|
||||
'BaseObject' => 'om/BaseObject.php',
|
||||
'NodeObject' => 'om/NodeObject.php',
|
||||
'Persistent' => 'om/Persistent.php',
|
||||
'PreOrderNodeIterator' => 'om/PreOrderNodeIterator.php',
|
||||
'NestedSetPreOrderNodeIterator' => 'om/NestedSetPreOrderNodeIterator.php',
|
||||
'NestedSetRecursiveIterator' => 'om/NestedSetRecursiveIterator.php',
|
||||
|
||||
'Criteria' => 'query/Criteria.php',
|
||||
'Criterion' => 'query/Criterion.php',
|
||||
'CriterionIterator' => 'query/CriterionIterator.php',
|
||||
'Join' => 'query/Join.php',
|
||||
'ModelCriteria' => 'query/ModelCriteria.php',
|
||||
'ModelCriterion' => 'query/ModelCriterion.php',
|
||||
'ModelJoin' => 'query/ModelJoin.php',
|
||||
'PropelQuery' => 'query/PropelQuery.php',
|
||||
|
||||
'BasePeer' => 'util/BasePeer.php',
|
||||
'NodePeer' => 'util/NodePeer.php',
|
||||
'PeerInfo' => 'util/PeerInfo.php',
|
||||
'PropelAutoloader' => 'util/PropelAutoloader.php',
|
||||
'PropelColumnTypes' => 'util/PropelColumnTypes.php',
|
||||
'PropelConditionalProxy' => 'util/PropelConditionalProxy.php',
|
||||
'PropelModelPager' => 'util/PropelModelPager.php',
|
||||
'PropelPager' => 'util/PropelPager.php',
|
||||
'PropelDateTime' => 'util/PropelDateTime.php',
|
||||
|
||||
'BasicValidator' => 'validator/BasicValidator.php',
|
||||
'MatchValidator' => 'validator/MatchValidator.php',
|
||||
'MaxLengthValidator' => 'validator/MaxLengthValidator.php',
|
||||
'MaxValueValidator' => 'validator/MaxValueValidator.php',
|
||||
'MinLengthValidator' => 'validator/MinLengthValidator.php',
|
||||
'MinValueValidator' => 'validator/MinValueValidator.php',
|
||||
'NotMatchValidator' => 'validator/NotMatchValidator.php',
|
||||
'RequiredValidator' => 'validator/RequiredValidator.php',
|
||||
'UniqueValidator' => 'validator/UniqueValidator.php',
|
||||
'ValidValuesValidator' => 'validator/ValidValuesValidator.php',
|
||||
'ValidationFailed' => 'validator/ValidationFailed.php',
|
||||
);
|
||||
|
||||
/**
|
||||
* Initializes Propel
|
||||
*
|
||||
* @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();
|
||||
|
||||
// reset the connection map (this should enable runtime changes of connection params)
|
||||
self::$connectionMap = array();
|
||||
|
||||
if (isset(self::$configuration['classmap']) && is_array(self::$configuration['classmap'])) {
|
||||
PropelAutoloader::getInstance()->addClassPaths(self::$configuration['classmap']);
|
||||
PropelAutoloader::getInstance()->register();
|
||||
}
|
||||
|
||||
self::$isInit = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure Propel a PHP (array) config file.
|
||||
*
|
||||
* @param string Path (absolute or relative to include_path) to config file.
|
||||
*
|
||||
* @throws PropelException If configuration file cannot be opened.
|
||||
* (E_WARNING probably will also be raised by PHP)
|
||||
*/
|
||||
public static function configure($configFile)
|
||||
{
|
||||
$configuration = include($configFile);
|
||||
if ($configuration === false) {
|
||||
throw new PropelException("Unable to open configuration file: " . var_export($configFile, true));
|
||||
}
|
||||
self::setConfiguration($configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the logging system, if config is specified in the runtime configuration.
|
||||
*/
|
||||
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'];
|
||||
$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()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialization of Propel a PHP (array) configuration file.
|
||||
*
|
||||
* @param string $c The Propel configuration file path.
|
||||
*
|
||||
* @throws PropelException Any exceptions caught during processing will be
|
||||
* rethrown wrapped into a PropelException.
|
||||
*/
|
||||
public static function init($c)
|
||||
{
|
||||
self::configure($c);
|
||||
self::initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether Propel has already been initialized.
|
||||
*
|
||||
* @return bool True if Propel is already initialized.
|
||||
*/
|
||||
public static function isInit()
|
||||
{
|
||||
return self::$isInit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the configuration for Propel and all dependencies.
|
||||
*
|
||||
* @param mixed The Configuration (array or PropelConfiguration)
|
||||
*/
|
||||
public static function setConfiguration($c)
|
||||
{
|
||||
if (is_array($c)) {
|
||||
if (isset($c['propel']) && is_array($c['propel'])) {
|
||||
$c = $c['propel'];
|
||||
}
|
||||
$c = new PropelConfiguration($c);
|
||||
}
|
||||
self::$configuration = $c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the configuration for this component.
|
||||
*
|
||||
* @param int - PropelConfiguration::TYPE_ARRAY: return the configuration as an array
|
||||
* (for backward compatibility this is the default)
|
||||
* - PropelConfiguration::TYPE_ARRAY_FLAT: return the configuration as a flat array
|
||||
* ($config['name.space.item'])
|
||||
* - PropelConfiguration::TYPE_OBJECT: return the configuration as a PropelConfiguration instance
|
||||
* @return mixed The Configuration (array or PropelConfiguration)
|
||||
*/
|
||||
public static function getConfiguration($type = PropelConfiguration::TYPE_ARRAY)
|
||||
{
|
||||
return self::$configuration->getParameters($type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 The new logger to use. ([PEAR] Log or BasicLogger)
|
||||
*/
|
||||
public static function setLogger($logger)
|
||||
{
|
||||
self::$logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a logger, for example PEAR::Log, has been configured,
|
||||
* otherwise false.
|
||||
*
|
||||
* @return bool 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 The message that will be logged.
|
||||
* @param string The logging level.
|
||||
*
|
||||
* @return bool 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 The name of the database corresponding to the DatabaseMap to 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 is null!");
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset(self::$dbMaps[$name])) {
|
||||
$clazz = self::$databaseMapClass;
|
||||
self::$dbMaps[$name] = new $clazz($name);
|
||||
}
|
||||
|
||||
return self::$dbMaps[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the database map object to use for specified datasource.
|
||||
*
|
||||
* @param string $name The datasource name.
|
||||
* @param DatabaseMap $map The database map object to use for specified datasource.
|
||||
*/
|
||||
public static function setDatabaseMap($name, DatabaseMap $map)
|
||||
{
|
||||
if ($name === null) {
|
||||
$name = self::getDefaultDB();
|
||||
}
|
||||
self::$dbMaps[$name] = $map;
|
||||
}
|
||||
|
||||
/**
|
||||
* For replication, set whether to always force the use of a master connection.
|
||||
*
|
||||
* @param boolean $bit True or False
|
||||
*/
|
||||
public static function setForceMasterConnection($bit)
|
||||
{
|
||||
self::$forceMasterConnection = (bool) $bit;
|
||||
}
|
||||
|
||||
/**
|
||||
* For replication, whether to always force the use of a master connection.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function getForceMasterConnection()
|
||||
{
|
||||
return self::$forceMasterConnection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a Connection for specified datasource name.
|
||||
*
|
||||
* @param string $name The datasource name for the connection being set.
|
||||
* @param PropelPDO $con The PDO connection.
|
||||
* @param string $mode Whether this is a READ or WRITE connection (Propel::CONNECTION_READ, Propel::CONNECTION_WRITE)
|
||||
*/
|
||||
public static function setConnection($name, PropelPDO $con, $mode = Propel::CONNECTION_WRITE)
|
||||
{
|
||||
if ($name === null) {
|
||||
$name = self::getDefaultDB();
|
||||
}
|
||||
if ($mode == Propel::CONNECTION_READ) {
|
||||
self::$connectionMap[$name]['slave'] = $con;
|
||||
} else {
|
||||
self::$connectionMap[$name]['master'] = $con;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an already-opened PDO connection or opens a new one for passed-in db name.
|
||||
*
|
||||
* @param string $name The datasource name that is used to look up the DSN from the runtime configuation file.
|
||||
* @param string $mode The connection mode (this applies to replication systems).
|
||||
*
|
||||
* @return PDO A database connection
|
||||
*
|
||||
* @throws PropelException - if connection cannot be configured or initialized.
|
||||
*/
|
||||
public static function getConnection($name = null, $mode = Propel::CONNECTION_WRITE)
|
||||
{
|
||||
if ($name === null) {
|
||||
$name = self::getDefaultDB();
|
||||
}
|
||||
|
||||
// IF a WRITE-mode connection was requested
|
||||
// or Propel is configured to always use the master connection
|
||||
// THEN return the master connection.
|
||||
if ($mode != Propel::CONNECTION_READ || self::$forceMasterConnection) {
|
||||
return self::getMasterConnection($name);
|
||||
} else {
|
||||
return self::getSlaveConnection($name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an already-opened write PDO connection or opens a new one for passed-in db name.
|
||||
*
|
||||
* @param string $name The datasource name that is used to look up the DSN
|
||||
* from the runtime configuation file. Empty name not allowed.
|
||||
*
|
||||
* @return PDO A database connection
|
||||
*
|
||||
* @throws PropelException - if connection cannot be configured or initialized.
|
||||
*/
|
||||
public static function getMasterConnection($name)
|
||||
{
|
||||
if (!isset(self::$connectionMap[$name]['master'])) {
|
||||
// load connection parameter for master connection
|
||||
$conparams = isset(self::$configuration['datasources'][$name]['connection']) ? self::$configuration['datasources'][$name]['connection'] : null;
|
||||
if (empty($conparams)) {
|
||||
throw new PropelException('No connection information in your runtime configuration file for datasource ['.$name.']');
|
||||
}
|
||||
// initialize master connection
|
||||
$con = Propel::initConnection($conparams, $name);
|
||||
self::$connectionMap[$name]['master'] = $con;
|
||||
}
|
||||
|
||||
return self::$connectionMap[$name]['master'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an already-opened read PDO connection or opens a new one for passed-in db name.
|
||||
*
|
||||
* @param string $name The datasource name that is used to look up the DSN
|
||||
* from the runtime configuation file. Empty name not allowed.
|
||||
*
|
||||
* @return PDO A database connection
|
||||
*
|
||||
* @throws PropelException - if connection cannot be configured or initialized.
|
||||
*/
|
||||
public static function getSlaveConnection($name)
|
||||
{
|
||||
if (!isset(self::$connectionMap[$name]['slave'])) {
|
||||
|
||||
$slaveconfigs = isset(self::$configuration['datasources'][$name]['slaves']) ? self::$configuration['datasources'][$name]['slaves'] : null;
|
||||
|
||||
if (empty($slaveconfigs)) {
|
||||
// no slaves configured for this datasource
|
||||
// fallback to the master connection
|
||||
self::$connectionMap[$name]['slave'] = self::getMasterConnection($name);
|
||||
} else {
|
||||
// Initialize a new slave
|
||||
if (isset($slaveconfigs['connection']['dsn'])) {
|
||||
// only one slave connection configured
|
||||
$conparams = $slaveconfigs['connection'];
|
||||
} else {
|
||||
// more than one sleve connection configured
|
||||
// pickup a random one
|
||||
$randkey = array_rand($slaveconfigs['connection']);
|
||||
$conparams = $slaveconfigs['connection'][$randkey];
|
||||
if (empty($conparams)) {
|
||||
throw new PropelException('No connection information in your runtime configuration file for SLAVE ['.$randkey.'] to datasource ['.$name.']');
|
||||
}
|
||||
}
|
||||
|
||||
// initialize slave connection
|
||||
$con = Propel::initConnection($conparams, $name);
|
||||
self::$connectionMap[$name]['slave'] = $con;
|
||||
}
|
||||
|
||||
} // if datasource slave not set
|
||||
|
||||
return self::$connectionMap[$name]['slave'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a new PDO connection for passed-in db name.
|
||||
*
|
||||
* @param array $conparams Connection paramters.
|
||||
* @param string $name Datasource name.
|
||||
* @param string $defaultClass The PDO subclass to instantiate if there is no explicit classname
|
||||
* specified in the connection params (default is Propel::CLASS_PROPEL_PDO)
|
||||
*
|
||||
* @return PDO A database connection of the given class (PDO, PropelPDO, SlavePDO or user-defined)
|
||||
*
|
||||
* @throws PropelException - if lower-level exception caught when trying to connect.
|
||||
*/
|
||||
public static function initConnection($conparams, $name, $defaultClass = Propel::CLASS_PROPEL_PDO)
|
||||
{
|
||||
|
||||
$dsn = $conparams['dsn'];
|
||||
if ($dsn === null) {
|
||||
throw new PropelException('No dsn specified in your connection parameters for datasource ['.$name.']');
|
||||
}
|
||||
|
||||
if (isset($conparams['classname']) && !empty($conparams['classname'])) {
|
||||
$classname = $conparams['classname'];
|
||||
if (!class_exists($classname)) {
|
||||
throw new PropelException('Unable to load specified PDO subclass: ' . $classname);
|
||||
}
|
||||
} else {
|
||||
$classname = $defaultClass;
|
||||
}
|
||||
|
||||
$user = isset($conparams['user']) ? $conparams['user'] : null;
|
||||
$password = isset($conparams['password']) ? $conparams['password'] : null;
|
||||
|
||||
// load any driver options from the config file
|
||||
// driver options are those PDO settings that have to be passed during the connection construction
|
||||
$driver_options = array();
|
||||
if ( isset($conparams['options']) && is_array($conparams['options']) ) {
|
||||
try {
|
||||
self::processDriverOptions( $conparams['options'], $driver_options );
|
||||
} catch (PropelException $e) {
|
||||
throw new PropelException('Error processing driver options for datasource ['.$name.']', $e);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$con = new $classname($dsn, $user, $password, $driver_options);
|
||||
$con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
if (Propel::getConfiguration(PropelConfiguration::TYPE_OBJECT)->getParameter('debugpdo.logging.enabled', false)) {
|
||||
$con->useLogging(true);
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
throw new PropelException("Unable to open PDO connection", $e);
|
||||
}
|
||||
|
||||
// load any connection options from the config file
|
||||
// connection attributes are those PDO flags that have to be set on the initialized connection
|
||||
if (isset($conparams['attributes']) && is_array($conparams['attributes'])) {
|
||||
$attributes = array();
|
||||
try {
|
||||
self::processDriverOptions( $conparams['attributes'], $attributes );
|
||||
} catch (PropelException $e) {
|
||||
throw new PropelException('Error processing connection attributes for datasource ['.$name.']', $e);
|
||||
}
|
||||
foreach ($attributes as $key => $value) {
|
||||
$con->setAttribute($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
// initialize the connection using the settings provided in the config file. this could be a "SET NAMES <charset>" query for MySQL, for instance
|
||||
$adapter = self::getDB($name);
|
||||
$adapter->initConnection($con, isset($conparams['settings']) && is_array($conparams['settings']) ? $conparams['settings'] : array());
|
||||
|
||||
return $con;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function to handle driver options or conneciton attributes in PDO.
|
||||
*
|
||||
* Process the INI file flags to be passed to each connection.
|
||||
*
|
||||
* @param array Where to find the list of constant flags and their new setting.
|
||||
* @param array Put the data into here
|
||||
*
|
||||
* @throws PropelException If invalid options were specified.
|
||||
*/
|
||||
private static function processDriverOptions($source, &$write_to)
|
||||
{
|
||||
foreach ($source as $option => $optiondata) {
|
||||
if (is_string($option) && strpos($option, '::') !== false) {
|
||||
$key = $option;
|
||||
} elseif (is_string($option)) {
|
||||
$key = 'PropelPDO::' . $option;
|
||||
}
|
||||
if (!defined($key)) {
|
||||
throw new PropelException("Invalid PDO option/attribute name specified: ".$key);
|
||||
}
|
||||
$key = constant($key);
|
||||
|
||||
$value = $optiondata['value'];
|
||||
if (is_string($value) && strpos($value, '::') !== false) {
|
||||
if (!defined($value)) {
|
||||
throw new PropelException("Invalid PDO option/attribute value specified: ".$value);
|
||||
}
|
||||
$value = constant($value);
|
||||
}
|
||||
|
||||
$write_to[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns database adapter for a specific datasource.
|
||||
*
|
||||
* @param string The datasource 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])) {
|
||||
if (!isset(self::$configuration['datasources'][$name]['adapter'])) {
|
||||
throw new PropelException("Unable to find adapter for datasource [" . $name . "].");
|
||||
}
|
||||
$db = DBAdapter::factory(self::$configuration['datasources'][$name]['adapter']);
|
||||
// register the adapter for this name
|
||||
self::$adapterMap[$name] = $db;
|
||||
}
|
||||
|
||||
return self::$adapterMap[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a database adapter for specified datasource.
|
||||
*
|
||||
* @param string $name The datasource name.
|
||||
* @param DBAdapter $adapter The DBAdapter implementation to use.
|
||||
*/
|
||||
public static function setDB($name, DBAdapter $adapter)
|
||||
{
|
||||
if ($name === null) {
|
||||
$name = self::getDefaultDB();
|
||||
}
|
||||
self::$adapterMap[$name] = $adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the default database.
|
||||
*
|
||||
* @return string Name of the default DB
|
||||
*/
|
||||
public static function getDefaultDB()
|
||||
{
|
||||
if (self::$defaultDBName === null) {
|
||||
// Determine default database name.
|
||||
self::$defaultDBName = isset(self::$configuration['datasources']['default']) ? self::$configuration['datasources']['default'] : self::DEFAULT_NAME;
|
||||
}
|
||||
return self::$defaultDBName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes any associated resource handles.
|
||||
*
|
||||
* This method frees any database connection handles that have been
|
||||
* opened by the getConnection() method.
|
||||
*/
|
||||
public static function close()
|
||||
{
|
||||
foreach (self::$connectionMap as $idx => $cons) {
|
||||
// Propel::log("Closing connections for " . $idx, Propel::LOG_DEBUG);
|
||||
unset(self::$connectionMap[$idx]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoload function for loading propel dependencies.
|
||||
*
|
||||
* @param string The class name needing loading.
|
||||
*
|
||||
* @return boolean TRUE if the class was loaded, false otherwise.
|
||||
*/
|
||||
public static function autoload($className)
|
||||
{
|
||||
if (isset(self::$autoloadMap[$className])) {
|
||||
require self::$baseDir . self::$autoloadMap[$className];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the base directory for the autoloader.
|
||||
* Avoids a call to dirname(__FILE__) each time self::autoload() is called.
|
||||
* FIXME put in the constructor if the Propel class ever becomes a singleton
|
||||
*/
|
||||
public static function initBaseDir()
|
||||
{
|
||||
self::$baseDir = dirname(__FILE__) . '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Include once a file specified in DOT notation and return unqualified classname.
|
||||
*
|
||||
* Typically, Propel uses autoload is used to load classes and expects that all classes
|
||||
* referenced within Propel are included in Propel's autoload map. This method is only
|
||||
* called when a specific non-Propel classname was specified -- for example, the
|
||||
* classname of a validator in the schema.xml. This method will attempt to include that
|
||||
* class via autoload and then relative to a location on the include_path.
|
||||
*
|
||||
* @param string $class dot-path to clas (e.g. path.to.my.ClassName).
|
||||
* @return string unqualified classname
|
||||
*/
|
||||
public static function importClass($path) {
|
||||
|
||||
// extract classname
|
||||
if (($pos = strrpos($path, '.')) === false) {
|
||||
$class = $path;
|
||||
} else {
|
||||
$class = substr($path, $pos + 1);
|
||||
}
|
||||
|
||||
// check if class exists, using autoloader to attempt to load it.
|
||||
if (class_exists($class, $useAutoload=true)) {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set your own class-name for Database-Mapping. Then
|
||||
* you can change the whole TableMap-Model, but keep its
|
||||
* functionality for Criteria.
|
||||
*
|
||||
* @param string The name of the class.
|
||||
*/
|
||||
public static function setDatabaseMapClass($name)
|
||||
{
|
||||
self::$databaseMapClass = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable instance pooling.
|
||||
*
|
||||
* @return boolean true if the method changed the instance pooling state,
|
||||
* false if it was already disabled
|
||||
*/
|
||||
public static function disableInstancePooling()
|
||||
{
|
||||
if (!self::$instancePoolingEnabled) {
|
||||
return false;
|
||||
}
|
||||
self::$instancePoolingEnabled = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable instance pooling (enabled by default).
|
||||
*
|
||||
* @return boolean true if the method changed the instance pooling state,
|
||||
* false if it was already enabled
|
||||
*/
|
||||
public static function enableInstancePooling()
|
||||
{
|
||||
if (self::$instancePoolingEnabled) {
|
||||
return false;
|
||||
}
|
||||
self::$instancePoolingEnabled = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* the instance pooling behaviour. True by default.
|
||||
*
|
||||
* @return boolean Whether the pooling is enabled or not.
|
||||
*/
|
||||
public static function isInstancePoolingEnabled()
|
||||
{
|
||||
return self::$instancePoolingEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
// Since the Propel class is not a true singleton, this code cannot go into the __construct()
|
||||
Propel::initBaseDir();
|
||||
spl_autoload_register(array('Propel', 'autoload'));
|
297
library/propel/runtime/lib/adapter/DBAdapter.php
Normal file
297
library/propel/runtime/lib/adapter/DBAdapter.php
Normal file
|
@ -0,0 +1,297 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* DBAdapter</code> defines the interface for a Propel database adapter.
|
||||
*
|
||||
* <p>Support for new databases is added by subclassing
|
||||
* <code>DBAdapter</code> and implementing its abstract interface, and by
|
||||
* registering the new database adapter and corresponding Propel
|
||||
* driver in the private adapters map (array) in this class.</p>
|
||||
*
|
||||
* <p>The Propel database adapters exist to present a uniform
|
||||
* interface to database access across all available databases. Once
|
||||
* the necessary adapters have been written and configured,
|
||||
* transparent swapping of databases is theoretically supported with
|
||||
* <i>zero code change</i> and minimal configuration file
|
||||
* modifications.</p>
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org> (Propel)
|
||||
* @author Jon S. Stevens <jon@latchkey.com> (Torque)
|
||||
* @author Brett McLaughlin <bmclaugh@algx.net> (Torque)
|
||||
* @author Daniel Rall <dlr@finemaltcoding.com> (Torque)
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.adapter
|
||||
*/
|
||||
abstract class DBAdapter
|
||||
{
|
||||
|
||||
const ID_METHOD_NONE = 0;
|
||||
const ID_METHOD_AUTOINCREMENT = 1;
|
||||
const ID_METHOD_SEQUENCE = 2;
|
||||
|
||||
/**
|
||||
* Propel driver to Propel adapter map.
|
||||
* @var array
|
||||
*/
|
||||
private static $adapters = array(
|
||||
'mysql' => 'DBMySQL',
|
||||
'mysqli' => 'DBMySQLi',
|
||||
'mssql' => 'DBMSSQL',
|
||||
'dblib' => 'DBMSSQL',
|
||||
'sybase' => 'DBSybase',
|
||||
'oracle' => 'DBOracle',
|
||||
'oci' => 'DBOracle',
|
||||
'pgsql' => 'DBPostgres',
|
||||
'sqlite' => 'DBSQLite',
|
||||
'' => 'DBNone',
|
||||
);
|
||||
|
||||
/**
|
||||
* Creates a new instance of the database adapter associated
|
||||
* with the specified Propel driver.
|
||||
*
|
||||
* @param string $driver The name of the Propel driver to
|
||||
* create a new adapter instance for or a shorter form adapter key.
|
||||
* @return DBAdapter An instance of a Propel database adapter.
|
||||
* @throws PropelException if the adapter could not be instantiated.
|
||||
*/
|
||||
public static function factory($driver) {
|
||||
$adapterClass = isset(self::$adapters[$driver]) ? self::$adapters[$driver] : null;
|
||||
if ($adapterClass !== null) {
|
||||
$a = new $adapterClass();
|
||||
return $a;
|
||||
} else {
|
||||
throw new PropelException("Unsupported Propel driver: " . $driver . ": Check your configuration file");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called after a connection was created to run necessary
|
||||
* post-initialization queries or code.
|
||||
*
|
||||
* If a charset was specified, this will be set before any other queries
|
||||
* are executed.
|
||||
*
|
||||
* This base method runs queries specified using the "query" setting.
|
||||
*
|
||||
* @param PDO A PDO connection instance.
|
||||
* @param array An array of settings.
|
||||
* @see setCharset()
|
||||
*/
|
||||
public function initConnection(PDO $con, array $settings)
|
||||
{
|
||||
if (isset($settings['charset']['value'])) {
|
||||
$this->setCharset($con, $settings['charset']['value']);
|
||||
}
|
||||
if (isset($settings['queries']) && is_array($settings['queries'])) {
|
||||
foreach ($settings['queries'] as $queries) {
|
||||
foreach ((array)$queries as $query) {
|
||||
$con->exec($query);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the character encoding using SQL standard SET NAMES statement.
|
||||
*
|
||||
* This method is invoked from the default initConnection() method and must
|
||||
* be overridden for an RDMBS which does _not_ support this SQL standard.
|
||||
*
|
||||
* @param PDO A PDO connection instance.
|
||||
* @param string The charset encoding.
|
||||
* @see initConnection()
|
||||
*/
|
||||
public function setCharset(PDO $con, $charset)
|
||||
{
|
||||
$con->exec("SET NAMES '" . $charset . "'");
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to ignore case.
|
||||
*
|
||||
* @param string The string to transform to upper case.
|
||||
* @return string The upper case string.
|
||||
*/
|
||||
public abstract function toUpperCase($in);
|
||||
|
||||
/**
|
||||
* Returns the character used to indicate the beginning and end of
|
||||
* a piece of text used in a SQL statement (generally a single
|
||||
* quote).
|
||||
*
|
||||
* @return string The text delimeter.
|
||||
*/
|
||||
public function getStringDelimiter()
|
||||
{
|
||||
return '\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to ignore case.
|
||||
*
|
||||
* @param string $in The string whose case to ignore.
|
||||
* @return string The string in a case that can be ignored.
|
||||
*/
|
||||
public abstract function ignoreCase($in);
|
||||
|
||||
/**
|
||||
* This method is used to ignore case in an ORDER BY clause.
|
||||
* Usually it is the same as ignoreCase, but some databases
|
||||
* (Interbase for example) does not use the same SQL in ORDER BY
|
||||
* and other clauses.
|
||||
*
|
||||
* @param string $in The string whose case to ignore.
|
||||
* @return string The string in a case that can be ignored.
|
||||
*/
|
||||
public function ignoreCaseInOrderBy($in)
|
||||
{
|
||||
return $this->ignoreCase($in);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns SQL which concatenates the second string to the first.
|
||||
*
|
||||
* @param string String to concatenate.
|
||||
* @param string String to append.
|
||||
* @return string
|
||||
*/
|
||||
public abstract function concatString($s1, $s2);
|
||||
|
||||
/**
|
||||
* Returns SQL which extracts a substring.
|
||||
*
|
||||
* @param string String to extract from.
|
||||
* @param int Offset to start from.
|
||||
* @param int Number of characters to extract.
|
||||
* @return string
|
||||
*/
|
||||
public abstract function subString($s, $pos, $len);
|
||||
|
||||
/**
|
||||
* Returns SQL which calculates the length (in chars) of a string.
|
||||
*
|
||||
* @param string String to calculate length of.
|
||||
* @return string
|
||||
*/
|
||||
public abstract function strLength($s);
|
||||
|
||||
|
||||
/**
|
||||
* Quotes database objec identifiers (table names, col names, sequences, etc.).
|
||||
* @param string $text The identifier to quote.
|
||||
* @return string The quoted identifier.
|
||||
*/
|
||||
public function quoteIdentifier($text)
|
||||
{
|
||||
return '"' . $text . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quotes a database table which could have space seperating it from an alias, both should be identified seperately
|
||||
* @param string $table The table name to quo
|
||||
* @return string The quoted table name
|
||||
**/
|
||||
public function quoteIdentifierTable($table) {
|
||||
return implode(" ", array_map(array($this, "quoteIdentifier"), explode(" ", $table) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the native ID method for this RDBMS.
|
||||
* @return int one of DBAdapter:ID_METHOD_SEQUENCE, DBAdapter::ID_METHOD_AUTOINCREMENT.
|
||||
*/
|
||||
protected function getIdMethod()
|
||||
{
|
||||
return DBAdapter::ID_METHOD_AUTOINCREMENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this adapter uses an ID generation system that requires getting ID _before_ performing INSERT.
|
||||
* @return boolean
|
||||
*/
|
||||
public function isGetIdBeforeInsert()
|
||||
{
|
||||
return ($this->getIdMethod() === DBAdapter::ID_METHOD_SEQUENCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this adapter uses an ID generation system that requires getting ID _before_ performing INSERT.
|
||||
* @return boolean
|
||||
*/
|
||||
public function isGetIdAfterInsert()
|
||||
{
|
||||
return ($this->getIdMethod() === DBAdapter::ID_METHOD_AUTOINCREMENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the generated ID (either last ID for autoincrement or next sequence ID).
|
||||
* @return mixed
|
||||
*/
|
||||
public function getId(PDO $con, $name = null)
|
||||
{
|
||||
return $con->lastInsertId($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns timestamp formatter string for use in date() function.
|
||||
* @return string
|
||||
*/
|
||||
public function getTimestampFormatter()
|
||||
{
|
||||
return "Y-m-d H:i:s";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns date formatter string for use in date() function.
|
||||
* @return string
|
||||
*/
|
||||
public function getDateFormatter()
|
||||
{
|
||||
return "Y-m-d";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns time formatter string for use in date() function.
|
||||
* @return string
|
||||
*/
|
||||
public function getTimeFormatter()
|
||||
{
|
||||
return "H:i:s";
|
||||
}
|
||||
|
||||
/**
|
||||
* Should Column-Names get identifiers for inserts or updates.
|
||||
* By default false is returned -> backwards compability.
|
||||
*
|
||||
* it`s a workaround...!!!
|
||||
*
|
||||
* @todo should be abstract
|
||||
* @return boolean
|
||||
* @deprecated
|
||||
*/
|
||||
public function useQuoteIdentifier()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the passed-in SQL to add LIMIT and/or OFFSET.
|
||||
*/
|
||||
public abstract function applyLimit(&$sql, $offset, $limit);
|
||||
|
||||
/**
|
||||
* Gets the SQL string that this adapter uses for getting a random number.
|
||||
*
|
||||
* @param mixed $seed (optional) seed value for databases that support this
|
||||
*/
|
||||
public abstract function random($seed = null);
|
||||
|
||||
}
|
215
library/propel/runtime/lib/adapter/DBMSSQL.php
Normal file
215
library/propel/runtime/lib/adapter/DBMSSQL.php
Normal file
|
@ -0,0 +1,215 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is used to connect to a MSSQL database.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org> (Propel)
|
||||
* @version $Revision: 1700 $
|
||||
* @package propel.runtime.adapter
|
||||
*/
|
||||
class DBMSSQL extends DBAdapter
|
||||
{
|
||||
|
||||
/**
|
||||
* This method is used to ignore case.
|
||||
*
|
||||
* @param in The string to transform to upper case.
|
||||
* @return The upper case string.
|
||||
*/
|
||||
public function toUpperCase($in)
|
||||
{
|
||||
return $this->ignoreCase($in);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to ignore case.
|
||||
*
|
||||
* @param in The string whose case to ignore.
|
||||
* @return The string in a case that can be ignored.
|
||||
*/
|
||||
public function ignoreCase($in)
|
||||
{
|
||||
return 'UPPER(' . $in . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns SQL which concatenates the second string to the first.
|
||||
*
|
||||
* @param string String to concatenate.
|
||||
* @param string String to append.
|
||||
* @return string
|
||||
*/
|
||||
public function concatString($s1, $s2)
|
||||
{
|
||||
return '(' . $s1 . ' + ' . $s2 . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns SQL which extracts a substring.
|
||||
*
|
||||
* @param string String to extract from.
|
||||
* @param int Offset to start from.
|
||||
* @param int Number of characters to extract.
|
||||
* @return string
|
||||
*/
|
||||
public function subString($s, $pos, $len)
|
||||
{
|
||||
return 'SUBSTRING(' . $s . ', ' . $pos . ', ' . $len . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns SQL which calculates the length (in chars) of a string.
|
||||
*
|
||||
* @param string String to calculate length of.
|
||||
* @return string
|
||||
*/
|
||||
public function strLength($s)
|
||||
{
|
||||
return 'LEN(' . $s . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DBAdapter::quoteIdentifier()
|
||||
*/
|
||||
public function quoteIdentifier($text)
|
||||
{
|
||||
return '[' . $text . ']';
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DBAdapter::random()
|
||||
*/
|
||||
public function random($seed = null)
|
||||
{
|
||||
return 'RAND(' . ((int)$seed) . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulated Limit/Offset
|
||||
* This rewrites the $sql query to apply the offset and limit.
|
||||
* some of the ORDER BY logic borrowed from Doctrine MsSqlPlatform
|
||||
* @see DBAdapter::applyLimit()
|
||||
* @author Benjamin Runnels <kraven@kraven.org>
|
||||
*/
|
||||
public function applyLimit(&$sql, $offset, $limit)
|
||||
{
|
||||
// make sure offset and limit are numeric
|
||||
if(! is_numeric($offset) || ! is_numeric($limit))
|
||||
{
|
||||
throw new PropelException('DBMSSQL::applyLimit() expects a number for argument 2 and 3');
|
||||
}
|
||||
|
||||
//split the select and from clauses out of the original query
|
||||
$selectSegment = array();
|
||||
|
||||
$selectText = 'SELECT ';
|
||||
|
||||
if (preg_match('/\Aselect(\s+)distinct/i', $sql)) {
|
||||
$selectText .= 'DISTINCT ';
|
||||
}
|
||||
|
||||
preg_match('/\Aselect(.*)from(.*)/si', $sql, $selectSegment);
|
||||
if(count($selectSegment) == 3) {
|
||||
$selectStatement = trim($selectSegment[1]);
|
||||
$fromStatement = trim($selectSegment[2]);
|
||||
} else {
|
||||
throw new Exception('DBMSSQL::applyLimit() could not locate the select statement at the start of the query.');
|
||||
}
|
||||
|
||||
// if we're starting at offset 0 then theres no need to simulate limit,
|
||||
// just grab the top $limit number of rows
|
||||
if($offset == 0) {
|
||||
$sql = $selectText . 'TOP ' . $limit . ' ' . $selectStatement . ' FROM ' . $fromStatement;
|
||||
return;
|
||||
}
|
||||
|
||||
//get the ORDER BY clause if present
|
||||
$orderStatement = stristr($fromStatement, 'ORDER BY');
|
||||
$orders = '';
|
||||
|
||||
if($orderStatement !== false) {
|
||||
//remove order statement from the from statement
|
||||
$fromStatement = trim(str_replace($orderStatement, '', $fromStatement));
|
||||
|
||||
$order = str_ireplace('ORDER BY', '', $orderStatement);
|
||||
$orders = explode(',', $order);
|
||||
|
||||
for($i = 0; $i < count($orders); $i ++) {
|
||||
$orderArr[trim(preg_replace('/\s+(ASC|DESC)$/i', '', $orders[$i]))] = array(
|
||||
'sort' => (stripos($orders[$i], ' DESC') !== false) ? 'DESC' : 'ASC',
|
||||
'key' => $i
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//setup inner and outer select selects
|
||||
$innerSelect = '';
|
||||
$outerSelect = '';
|
||||
foreach(explode(', ', $selectStatement) as $selCol) {
|
||||
$selColArr = explode(' ', $selCol);
|
||||
$selColCount = count($selColArr) - 1;
|
||||
|
||||
//make sure the current column isn't * or an aggregate
|
||||
if($selColArr[0] != '*' && ! strstr($selColArr[0], '(')) {
|
||||
if(isset($orderArr[$selColArr[0]])) {
|
||||
$orders[$orderArr[$selColArr[0]]['key']] = $selColArr[0] . ' ' . $orderArr[$selColArr[0]]['sort'];
|
||||
}
|
||||
|
||||
//use the alias if one was present otherwise use the column name
|
||||
$alias = (! stristr($selCol, ' AS ')) ? $this->quoteIdentifier($selColArr[0]) : $this->quoteIdentifier($selColArr[$selColCount]);
|
||||
|
||||
//save the first non-aggregate column for use in ROW_NUMBER() if required
|
||||
if(! isset($firstColumnOrderStatement)) {
|
||||
$firstColumnOrderStatement = 'ORDER BY ' . $selColArr[0];
|
||||
}
|
||||
|
||||
//add an alias to the inner select so all columns will be unique
|
||||
$innerSelect .= $selColArr[0] . ' AS ' . $alias . ', ';
|
||||
$outerSelect .= $alias . ', ';
|
||||
} else {
|
||||
//agregate columns must always have an alias clause
|
||||
if(! stristr($selCol, ' AS ')) {
|
||||
throw new Exception('DBMSSQL::applyLimit() requires aggregate columns to have an Alias clause');
|
||||
}
|
||||
|
||||
//aggregate column alias can't be used as the count column you must use the entire aggregate statement
|
||||
if(isset($orderArr[$selColArr[$selColCount]])) {
|
||||
$orders[$orderArr[$selColArr[$selColCount]]['key']] = str_replace($selColArr[$selColCount - 1] . ' ' . $selColArr[$selColCount], '', $selCol) . $orderArr[$selColArr[$selColCount]]['sort'];
|
||||
}
|
||||
|
||||
//quote the alias
|
||||
$alias = $this->quoteIdentifier($selColArr[$selColCount]);
|
||||
$innerSelect .= str_replace($selColArr[$selColCount], $alias, $selCol) . ', ';
|
||||
$outerSelect .= $alias . ', ';
|
||||
}
|
||||
}
|
||||
|
||||
if(is_array($orders)) {
|
||||
$orderStatement = 'ORDER BY ' . implode(', ', $orders);
|
||||
} else {
|
||||
//use the first non aggregate column in our select statement if no ORDER BY clause present
|
||||
if(isset($firstColumnOrderStatement)) {
|
||||
$orderStatement = $firstColumnOrderStatement;
|
||||
} else {
|
||||
throw new Exception('DBMSSQL::applyLimit() unable to find column to use with ROW_NUMBER()');
|
||||
}
|
||||
}
|
||||
|
||||
//substring the select strings to get rid of the last comma and add our FROM and SELECT clauses
|
||||
$innerSelect = $selectText . 'ROW_NUMBER() OVER(' . $orderStatement . ') AS RowNumber, ' . substr($innerSelect, 0, - 2) . ' FROM';
|
||||
//outer select can't use * because of the RowNumber column
|
||||
$outerSelect = 'SELECT ' . substr($outerSelect, 0, - 2) . ' FROM';
|
||||
|
||||
//ROW_NUMBER() starts at 1 not 0
|
||||
$sql = $outerSelect . ' (' . $innerSelect . ' ' . $fromStatement . ') AS derivedb WHERE RowNumber BETWEEN ' . ($offset + 1) . ' AND ' . ($limit + $offset);
|
||||
return;
|
||||
}
|
||||
}
|
145
library/propel/runtime/lib/adapter/DBMySQL.php
Normal file
145
library/propel/runtime/lib/adapter/DBMySQL.php
Normal file
|
@ -0,0 +1,145 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is used in order to connect to a MySQL database.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org> (Propel)
|
||||
* @author Jon S. Stevens <jon@clearink.com> (Torque)
|
||||
* @author Brett McLaughlin <bmclaugh@algx.net> (Torque)
|
||||
* @author Daniel Rall <dlr@finemaltcoding.com> (Torque)
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.adapter
|
||||
*/
|
||||
class DBMySQL extends DBAdapter
|
||||
{
|
||||
|
||||
/**
|
||||
* This method is used to ignore case.
|
||||
*
|
||||
* @param in The string to transform to upper case.
|
||||
* @return The upper case string.
|
||||
*/
|
||||
public function toUpperCase($in)
|
||||
{
|
||||
return "UPPER(" . $in . ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to ignore case.
|
||||
*
|
||||
* @param in The string whose case to ignore.
|
||||
* @return The string in a case that can be ignored.
|
||||
*/
|
||||
public function ignoreCase($in)
|
||||
{
|
||||
return "UPPER(" . $in . ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns SQL which concatenates the second string to the first.
|
||||
*
|
||||
* @param string String to concatenate.
|
||||
* @param string String to append.
|
||||
* @return string
|
||||
*/
|
||||
public function concatString($s1, $s2)
|
||||
{
|
||||
return "CONCAT($s1, $s2)";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns SQL which extracts a substring.
|
||||
*
|
||||
* @param string String to extract from.
|
||||
* @param int Offset to start from.
|
||||
* @param int Number of characters to extract.
|
||||
* @return string
|
||||
*/
|
||||
public function subString($s, $pos, $len)
|
||||
{
|
||||
return "SUBSTRING($s, $pos, $len)";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns SQL which calculates the length (in chars) of a string.
|
||||
*
|
||||
* @param string String to calculate length of.
|
||||
* @return string
|
||||
*/
|
||||
public function strLength($s)
|
||||
{
|
||||
return "CHAR_LENGTH($s)";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Locks the specified table.
|
||||
*
|
||||
* @param Connection $con The Propel connection to use.
|
||||
* @param string $table The name of the table to lock.
|
||||
* @throws PDOException No Statement could be created or
|
||||
* executed.
|
||||
*/
|
||||
public function lockTable(PDO $con, $table)
|
||||
{
|
||||
$con->exec("LOCK TABLE " . $table . " WRITE");
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlocks the specified table.
|
||||
*
|
||||
* @param PDO $con The PDO connection to use.
|
||||
* @param string $table The name of the table to unlock.
|
||||
* @throws PDOException No Statement could be created or
|
||||
* executed.
|
||||
*/
|
||||
public function unlockTable(PDO $con, $table)
|
||||
{
|
||||
$statement = $con->exec("UNLOCK TABLES");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DBAdapter::quoteIdentifier()
|
||||
*/
|
||||
public function quoteIdentifier($text)
|
||||
{
|
||||
return '`' . $text . '`';
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DBAdapter::useQuoteIdentifier()
|
||||
*/
|
||||
public function useQuoteIdentifier()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DBAdapter::applyLimit()
|
||||
*/
|
||||
public function applyLimit(&$sql, $offset, $limit)
|
||||
{
|
||||
if ( $limit > 0 ) {
|
||||
$sql .= " LIMIT " . ($offset > 0 ? $offset . ", " : "") . $limit;
|
||||
} else if ( $offset > 0 ) {
|
||||
$sql .= " LIMIT " . $offset . ", 18446744073709551615";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DBAdapter::random()
|
||||
*/
|
||||
public function random($seed = null)
|
||||
{
|
||||
return 'rand('.((int) $seed).')';
|
||||
}
|
||||
|
||||
}
|
104
library/propel/runtime/lib/adapter/DBNone.php
Normal file
104
library/propel/runtime/lib/adapter/DBNone.php
Normal file
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* This adapter is used when you do not have a database installed.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org> (Propel)
|
||||
* @author Jon S. Stevens <jon@clearink.com> (Torque)
|
||||
* @author Brett McLaughlin <bmclaugh@algx.net> (Torque)
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.adapter
|
||||
*/
|
||||
class DBNone extends DBAdapter
|
||||
{
|
||||
|
||||
/**
|
||||
* @see DBAdapter::initConnection()
|
||||
*/
|
||||
public function initConnection(PDO $con, array $settings)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to ignore case.
|
||||
*
|
||||
* @param in The string to transform to upper case.
|
||||
* @return The upper case string.
|
||||
*/
|
||||
public function toUpperCase($in)
|
||||
{
|
||||
return $in;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to ignore case.
|
||||
*
|
||||
* @param in The string whose case to ignore.
|
||||
* @return The string in a case that can be ignored.
|
||||
*/
|
||||
public function ignoreCase($in)
|
||||
{
|
||||
return $in;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns SQL which concatenates the second string to the first.
|
||||
*
|
||||
* @param string String to concatenate.
|
||||
* @param string String to append.
|
||||
* @return string
|
||||
*/
|
||||
public function concatString($s1, $s2)
|
||||
{
|
||||
return ($s1 . $s2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns SQL which extracts a substring.
|
||||
*
|
||||
* @param string String to extract from.
|
||||
* @param int Offset to start from.
|
||||
* @param int Number of characters to extract.
|
||||
* @return string
|
||||
*/
|
||||
public function subString($s, $pos, $len)
|
||||
{
|
||||
return substr($s, $pos, $len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns SQL which calculates the length (in chars) of a string.
|
||||
*
|
||||
* @param string String to calculate length of.
|
||||
* @return string
|
||||
*/
|
||||
public function strLength($s)
|
||||
{
|
||||
return strlen($s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the passed-in SQL to add LIMIT and/or OFFSET.
|
||||
*/
|
||||
public function applyLimit(&$sql, $offset, $limit)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SQL string that this adapter uses for getting a random number.
|
||||
*
|
||||
* @param mixed $seed (optional) seed value for databases that support this
|
||||
*/
|
||||
public function random($seed = null)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
150
library/propel/runtime/lib/adapter/DBOracle.php
Normal file
150
library/propel/runtime/lib/adapter/DBOracle.php
Normal file
|
@ -0,0 +1,150 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Oracle adapter.
|
||||
*
|
||||
* @author David Giffin <david@giffin.org> (Propel)
|
||||
* @author Hans Lellelid <hans@xmpl.org> (Propel)
|
||||
* @author Jon S. Stevens <jon@clearink.com> (Torque)
|
||||
* @author Brett McLaughlin <bmclaugh@algx.net> (Torque)
|
||||
* @author Bill Schneider <bschneider@vecna.com> (Torque)
|
||||
* @author Daniel Rall <dlr@finemaltcoding.com> (Torque)
|
||||
* @version $Revision: 1669 $
|
||||
* @package propel.runtime.adapter
|
||||
*/
|
||||
class DBOracle extends DBAdapter
|
||||
{
|
||||
/**
|
||||
* This method is called after a connection was created to run necessary
|
||||
* post-initialization queries or code.
|
||||
* Removes the charset query and adds the date queries
|
||||
*
|
||||
* @param PDO A PDO connection instance.
|
||||
* @see parent::initConnection()
|
||||
*/
|
||||
public function initConnection(PDO $con, array $settings)
|
||||
{
|
||||
$con->exec("ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD'");
|
||||
$con->exec("ALTER SESSION SET NLS_TIMESTAMP_FORMAT='YYYY-MM-DD HH24:MI:SS'");
|
||||
if (isset($settings['queries']) && is_array($settings['queries'])) {
|
||||
foreach ($settings['queries'] as $queries) {
|
||||
foreach ((array)$queries as $query) {
|
||||
$con->exec($query);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to ignore case.
|
||||
*
|
||||
* @param string $in The string to transform to upper case.
|
||||
* @return string The upper case string.
|
||||
*/
|
||||
public function toUpperCase($in)
|
||||
{
|
||||
return "UPPER(" . $in . ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to ignore case.
|
||||
*
|
||||
* @param string $in The string whose case to ignore.
|
||||
* @return string The string in a case that can be ignored.
|
||||
*/
|
||||
public function ignoreCase($in)
|
||||
{
|
||||
return "UPPER(" . $in . ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns SQL which concatenates the second string to the first.
|
||||
*
|
||||
* @param string String to concatenate.
|
||||
* @param string String to append.
|
||||
* @return string
|
||||
*/
|
||||
public function concatString($s1, $s2)
|
||||
{
|
||||
return "CONCAT($s1, $s2)";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns SQL which extracts a substring.
|
||||
*
|
||||
* @param string String to extract from.
|
||||
* @param int Offset to start from.
|
||||
* @param int Number of characters to extract.
|
||||
* @return string
|
||||
*/
|
||||
public function subString($s, $pos, $len)
|
||||
{
|
||||
return "SUBSTR($s, $pos, $len)";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns SQL which calculates the length (in chars) of a string.
|
||||
*
|
||||
* @param string String to calculate length of.
|
||||
* @return string
|
||||
*/
|
||||
public function strLength($s)
|
||||
{
|
||||
return "LENGTH($s)";
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DBAdapter::applyLimit()
|
||||
*/
|
||||
public function applyLimit(&$sql, $offset, $limit, $criteria = null)
|
||||
{
|
||||
if (BasePeer::needsSelectAliases($criteria)) {
|
||||
$selectSql = BasePeer::createSelectSqlPart($criteria, $params, true);
|
||||
$sql = $selectSql . substr($sql, strpos('FROM', $sql));
|
||||
}
|
||||
$sql = 'SELECT B.* FROM ('
|
||||
. 'SELECT A.*, rownum AS PROPEL_ROWNUM FROM (' . $sql . ') A '
|
||||
. ') B WHERE ';
|
||||
|
||||
if ( $offset > 0 ) {
|
||||
$sql .= ' B.PROPEL_ROWNUM > ' . $offset;
|
||||
if ( $limit > 0 ) {
|
||||
$sql .= ' AND B.PROPEL_ROWNUM <= ' . ( $offset + $limit );
|
||||
}
|
||||
} else {
|
||||
$sql .= ' B.PROPEL_ROWNUM <= ' . $limit;
|
||||
}
|
||||
}
|
||||
|
||||
protected function getIdMethod()
|
||||
{
|
||||
return DBAdapter::ID_METHOD_SEQUENCE;
|
||||
}
|
||||
|
||||
public function getId(PDO $con, $name = null)
|
||||
{
|
||||
if ($name === null) {
|
||||
throw new PropelException("Unable to fetch next sequence ID without sequence name.");
|
||||
}
|
||||
|
||||
$stmt = $con->query("SELECT " . $name . ".nextval FROM dual");
|
||||
$row = $stmt->fetch(PDO::FETCH_NUM);
|
||||
|
||||
return $row[0];
|
||||
}
|
||||
|
||||
public function random($seed=NULL)
|
||||
{
|
||||
return 'dbms_random.value';
|
||||
}
|
||||
|
||||
|
||||
}
|
141
library/propel/runtime/lib/adapter/DBPostgres.php
Normal file
141
library/propel/runtime/lib/adapter/DBPostgres.php
Normal file
|
@ -0,0 +1,141 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is used to connect to PostgresQL databases.
|
||||
*
|
||||
* <a href="http://www.pgsql.org">http://www.pgsql.org</a>
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org> (Propel)
|
||||
* @author Hakan Tandogan <hakan42@gmx.de> (Torque)
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.adapter
|
||||
*/
|
||||
class DBPostgres extends DBAdapter
|
||||
{
|
||||
|
||||
/**
|
||||
* This method is used to ignore case.
|
||||
*
|
||||
* @param string $in The string to transform to upper case.
|
||||
* @return string The upper case string.
|
||||
*/
|
||||
public function toUpperCase($in)
|
||||
{
|
||||
return "UPPER(" . $in . ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to ignore case.
|
||||
*
|
||||
* @param in The string whose case to ignore.
|
||||
* @return The string in a case that can be ignored.
|
||||
*/
|
||||
public function ignoreCase($in)
|
||||
{
|
||||
return "UPPER(" . $in . ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns SQL which concatenates the second string to the first.
|
||||
*
|
||||
* @param string String to concatenate.
|
||||
* @param string String to append.
|
||||
* @return string
|
||||
*/
|
||||
public function concatString($s1, $s2)
|
||||
{
|
||||
return "($s1 || $s2)";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns SQL which extracts a substring.
|
||||
*
|
||||
* @param string String to extract from.
|
||||
* @param int Offset to start from.
|
||||
* @param int Number of characters to extract.
|
||||
* @return string
|
||||
*/
|
||||
public function subString($s, $pos, $len)
|
||||
{
|
||||
return "substring($s from $pos" . ($len > -1 ? "for $len" : "") . ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns SQL which calculates the length (in chars) of a string.
|
||||
*
|
||||
* @param string String to calculate length of.
|
||||
* @return string
|
||||
*/
|
||||
public function strLength($s)
|
||||
{
|
||||
return "char_length($s)";
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DBAdapter::getIdMethod()
|
||||
*/
|
||||
protected function getIdMethod()
|
||||
{
|
||||
return DBAdapter::ID_METHOD_SEQUENCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets ID for specified sequence name.
|
||||
*/
|
||||
public function getId(PDO $con, $name = null)
|
||||
{
|
||||
if ($name === null) {
|
||||
throw new PropelException("Unable to fetch next sequence ID without sequence name.");
|
||||
}
|
||||
$stmt = $con->query("SELECT nextval(".$con->quote($name).")");
|
||||
$row = $stmt->fetch(PDO::FETCH_NUM);
|
||||
return $row[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns timestamp formatter string for use in date() function.
|
||||
* @return string
|
||||
*/
|
||||
public function getTimestampFormatter()
|
||||
{
|
||||
return "Y-m-d H:i:s O";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns timestamp formatter string for use in date() function.
|
||||
* @return string
|
||||
*/
|
||||
public function getTimeFormatter()
|
||||
{
|
||||
return "H:i:s O";
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DBAdapter::applyLimit()
|
||||
*/
|
||||
public function applyLimit(&$sql, $offset, $limit)
|
||||
{
|
||||
if ( $limit > 0 ) {
|
||||
$sql .= " LIMIT ".$limit;
|
||||
}
|
||||
if ( $offset > 0 ) {
|
||||
$sql .= " OFFSET ".$offset;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DBAdapter::random()
|
||||
*/
|
||||
public function random($seed=NULL)
|
||||
{
|
||||
return 'random()';
|
||||
}
|
||||
}
|
116
library/propel/runtime/lib/adapter/DBSQLite.php
Normal file
116
library/propel/runtime/lib/adapter/DBSQLite.php
Normal file
|
@ -0,0 +1,116 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is used in order to connect to a SQLite database.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.adapter
|
||||
*/
|
||||
class DBSQLite extends DBAdapter
|
||||
{
|
||||
|
||||
/**
|
||||
* For SQLite this method has no effect, since SQLite doesn't support specifying a character
|
||||
* set (or, another way to look at it, it doesn't require a single character set per DB).
|
||||
*
|
||||
* @param PDO A PDO connection instance.
|
||||
* @param string The charset encoding.
|
||||
* @throws PropelException If the specified charset doesn't match sqlite_libencoding()
|
||||
*/
|
||||
public function setCharset(PDO $con, $charset)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to ignore case.
|
||||
*
|
||||
* @param in The string to transform to upper case.
|
||||
* @return The upper case string.
|
||||
*/
|
||||
public function toUpperCase($in)
|
||||
{
|
||||
return 'UPPER(' . $in . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to ignore case.
|
||||
*
|
||||
* @param in The string whose case to ignore.
|
||||
* @return The string in a case that can be ignored.
|
||||
*/
|
||||
public function ignoreCase($in)
|
||||
{
|
||||
return 'UPPER(' . $in . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns SQL which concatenates the second string to the first.
|
||||
*
|
||||
* @param string String to concatenate.
|
||||
* @param string String to append.
|
||||
* @return string
|
||||
*/
|
||||
public function concatString($s1, $s2)
|
||||
{
|
||||
return "($s1 || $s2)";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns SQL which extracts a substring.
|
||||
*
|
||||
* @param string String to extract from.
|
||||
* @param int Offset to start from.
|
||||
* @param int Number of characters to extract.
|
||||
* @return string
|
||||
*/
|
||||
public function subString($s, $pos, $len)
|
||||
{
|
||||
return "substr($s, $pos, $len)";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns SQL which calculates the length (in chars) of a string.
|
||||
*
|
||||
* @param string String to calculate length of.
|
||||
* @return string
|
||||
*/
|
||||
public function strLength($s)
|
||||
{
|
||||
return "length($s)";
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DBAdapter::quoteIdentifier()
|
||||
*/
|
||||
public function quoteIdentifier($text)
|
||||
{
|
||||
return '[' . $text . ']';
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DBAdapter::applyLimit()
|
||||
*/
|
||||
public function applyLimit(&$sql, $offset, $limit)
|
||||
{
|
||||
if ( $limit > 0 ) {
|
||||
$sql .= " LIMIT " . $limit . ($offset > 0 ? " OFFSET " . $offset : "");
|
||||
} elseif ( $offset > 0 ) {
|
||||
$sql .= " LIMIT -1 OFFSET " . $offset;
|
||||
}
|
||||
}
|
||||
|
||||
public function random($seed=NULL)
|
||||
{
|
||||
return 'random()';
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* MSSQL Server returns datetimes in a format that strtotime doesn't handle so we need to extend DateTime
|
||||
*
|
||||
* @package propel.runtime.adapter.MSSQL
|
||||
*/
|
||||
class MssqlDateTime extends DateTime
|
||||
{
|
||||
public function __construct($datetime='now', DateTimeZone $tz = null)
|
||||
{
|
||||
//if the date is bad account for Mssql datetime format
|
||||
if ($datetime != 'now' && strtotime($datetime) === false)
|
||||
{
|
||||
$datetime = substr($datetime,0, -6).substr($datetime,-2);
|
||||
}
|
||||
|
||||
if($tz instanceof DateTimeZone)
|
||||
{
|
||||
parent::__construct($datetime,$tz);
|
||||
}
|
||||
else
|
||||
{
|
||||
parent::__construct($datetime);
|
||||
}
|
||||
}
|
||||
}
|
19
library/propel/runtime/lib/adapter/MSSQL/MssqlDebugPDO.php
Normal file
19
library/propel/runtime/lib/adapter/MSSQL/MssqlDebugPDO.php
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* dblib doesn't support transactions so we need to add a workaround for transactions, last insert ID, and quoting
|
||||
*
|
||||
* @package propel.runtime.adapter.MSSQL
|
||||
*/
|
||||
class MssqlDebugPDO extends MssqlPropelPDO
|
||||
{
|
||||
public $useDebug = true;
|
||||
}
|
132
library/propel/runtime/lib/adapter/MSSQL/MssqlPropelPDO.php
Normal file
132
library/propel/runtime/lib/adapter/MSSQL/MssqlPropelPDO.php
Normal file
|
@ -0,0 +1,132 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* dblib doesn't support transactions so we need to add a workaround for transactions, last insert ID, and quoting
|
||||
*
|
||||
* @package propel.runtime.adapter.MSSQL
|
||||
*/
|
||||
class MssqlPropelPDO extends PropelPDO
|
||||
{
|
||||
/**
|
||||
* Begin a transaction.
|
||||
*
|
||||
* It is necessary to override the abstract PDO transaction functions here, as
|
||||
* the PDO driver for MSSQL does not support transactions.
|
||||
*/
|
||||
public function beginTransaction()
|
||||
{
|
||||
$return = true;
|
||||
$opcount = $this->getNestedTransactionCount();
|
||||
if ( $opcount === 0 ) {
|
||||
$return = self::exec('BEGIN TRANSACTION');
|
||||
if ($this->useDebug) {
|
||||
$this->log('Begin transaction', null, __METHOD__);
|
||||
}
|
||||
$this->isUncommitable = false;
|
||||
}
|
||||
$this->nestedTransactionCount++;
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit a transaction.
|
||||
*
|
||||
* It is necessary to override the abstract PDO transaction functions here, as
|
||||
* the PDO driver for MSSQL does not support transactions.
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
$return = true;
|
||||
$opcount = $this->getNestedTransactionCount();
|
||||
if ($opcount > 0) {
|
||||
if ($opcount === 1) {
|
||||
if ($this->isUncommitable) {
|
||||
throw new PropelException('Cannot commit because a nested transaction was rolled back');
|
||||
} else {
|
||||
$return = self::exec('COMMIT TRANSACTION');
|
||||
if ($this->useDebug) {
|
||||
$this->log('Commit transaction', null, __METHOD__);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
$this->nestedTransactionCount--;
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Roll-back a transaction.
|
||||
*
|
||||
* It is necessary to override the abstract PDO transaction functions here, as
|
||||
* the PDO driver for MSSQL does not support transactions.
|
||||
*/
|
||||
public function rollBack()
|
||||
{
|
||||
$return = true;
|
||||
$opcount = $this->getNestedTransactionCount();
|
||||
if ($opcount > 0) {
|
||||
if ($opcount === 1) {
|
||||
$return = self::exec('ROLLBACK TRANSACTION');
|
||||
if ($this->useDebug) {
|
||||
$this->log('Rollback transaction', null, __METHOD__);
|
||||
}
|
||||
} else {
|
||||
$this->isUncommitable = true;
|
||||
}
|
||||
$this->nestedTransactionCount--;
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rollback the whole transaction, even if this is a nested rollback
|
||||
* and reset the nested transaction count to 0.
|
||||
*
|
||||
* It is necessary to override the abstract PDO transaction functions here, as
|
||||
* the PDO driver for MSSQL does not support transactions.
|
||||
*/
|
||||
public function forceRollBack()
|
||||
{
|
||||
$return = true;
|
||||
$opcount = $this->getNestedTransactionCount();
|
||||
if ($opcount > 0) {
|
||||
// If we're in a transaction, always roll it back
|
||||
// regardless of nesting level.
|
||||
$return = self::exec('ROLLBACK TRANSACTION');
|
||||
|
||||
// reset nested transaction count to 0 so that we don't
|
||||
// try to commit (or rollback) the transaction outside this scope.
|
||||
$this->nestedTransactionCount = 0;
|
||||
|
||||
if ($this->useDebug) {
|
||||
$this->log('Rollback transaction', null, __METHOD__);
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
public function lastInsertId($seqname = null)
|
||||
{
|
||||
$result = self::query('SELECT SCOPE_IDENTITY()');
|
||||
return (int) $result->fetchColumn();
|
||||
}
|
||||
|
||||
public function quoteIdentifier($text)
|
||||
{
|
||||
return '[' . $text . ']';
|
||||
}
|
||||
|
||||
public function useQuoteIdentifier()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
188
library/propel/runtime/lib/collection/PropelArrayCollection.php
Normal file
188
library/propel/runtime/lib/collection/PropelArrayCollection.php
Normal file
|
@ -0,0 +1,188 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class for iterating over a list of Propel objects stored as arrays
|
||||
*
|
||||
* @author Francois Zaninotto
|
||||
* @package propel.runtime.collection
|
||||
*/
|
||||
class PropelArrayCollection extends PropelCollection
|
||||
{
|
||||
protected $workerObject;
|
||||
|
||||
/**
|
||||
* Save all the elements in the collection
|
||||
*/
|
||||
public function save($con = null)
|
||||
{
|
||||
if (null === $con) {
|
||||
$con = $this->getConnection(Propel::CONNECTION_WRITE);
|
||||
}
|
||||
$con->beginTransaction();
|
||||
try {
|
||||
$obj = $this->getWorkerObject();
|
||||
foreach ($this as $element) {
|
||||
$obj->clear();
|
||||
$obj->fromArray($element);
|
||||
$obj->setNew($obj->isPrimaryKeyNull());
|
||||
$obj->save($con);
|
||||
}
|
||||
$con->commit();
|
||||
} catch (PropelException $e) {
|
||||
$con->rollback();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all the elements in the collection
|
||||
*/
|
||||
public function delete($con = null)
|
||||
{
|
||||
if (null === $con) {
|
||||
$con = $this->getConnection(Propel::CONNECTION_WRITE);
|
||||
}
|
||||
$con->beginTransaction();
|
||||
try {
|
||||
foreach ($this as $element) {
|
||||
$obj = $this->getWorkerObject();
|
||||
$obj->setDeleted(false);
|
||||
$obj->fromArray($element);
|
||||
$obj->delete($con);
|
||||
}
|
||||
$con->commit();
|
||||
} catch (PropelException $e) {
|
||||
$con->rollback();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of the primary keys of all the objects in the collection
|
||||
*
|
||||
* @return array The list of the primary keys of the collection
|
||||
*/
|
||||
public function getPrimaryKeys($usePrefix = true)
|
||||
{
|
||||
$callable = array($this->getPeerClass(), 'getPrimaryKeyFromRow');
|
||||
$ret = array();
|
||||
foreach ($this as $key => $element) {
|
||||
$key = $usePrefix ? ($this->getModel() . '_' . $key) : $key;
|
||||
$ret[$key]= call_user_func($callable, array_values($element));
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the collection from an array
|
||||
* Uses the object model to force the column types
|
||||
* Does not empty the collection before adding the data from the array
|
||||
*
|
||||
* @param array $arr
|
||||
*/
|
||||
public function fromArray($arr)
|
||||
{
|
||||
$obj = $this->getWorkerObject();
|
||||
foreach ($arr as $element) {
|
||||
$obj->clear();
|
||||
$obj->fromArray($element);
|
||||
$this->append($obj->toArray());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array representation of the collection
|
||||
* This is not an alias for getData(), since it returns a copy of the data
|
||||
*
|
||||
* @param string $keyColumn If null, the returned array uses an incremental index.
|
||||
* Otherwise, the array is indexed using the specified column
|
||||
* @param boolean $usePrefix If true, the returned array prefixes keys
|
||||
* with the model class name ('Article_0', 'Article_1', etc).
|
||||
*
|
||||
* <code>
|
||||
* $bookCollection->toArray();
|
||||
* array(
|
||||
* 0 => array('Id' => 123, 'Title' => 'War And Peace'),
|
||||
* 1 => array('Id' => 456, 'Title' => 'Don Juan'),
|
||||
* )
|
||||
* $bookCollection->toArray('Id');
|
||||
* array(
|
||||
* 123 => array('Id' => 123, 'Title' => 'War And Peace'),
|
||||
* 456 => array('Id' => 456, 'Title' => 'Don Juan'),
|
||||
* )
|
||||
* $bookCollection->toArray(null, true);
|
||||
* array(
|
||||
* 'Book_0' => array('Id' => 123, 'Title' => 'War And Peace'),
|
||||
* 'Book_1' => array('Id' => 456, 'Title' => 'Don Juan'),
|
||||
* )
|
||||
* </code>
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($keyColumn = null, $usePrefix = false)
|
||||
{
|
||||
$ret = array();
|
||||
foreach ($this as $key => $element) {
|
||||
$key = null === $keyColumn ? $key : $element[$keyColumn];
|
||||
$key = $usePrefix ? ($this->getModel() . '_' . $key) : $key;
|
||||
$ret[$key] = $element;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Synonym for toArray(), to provide a similar interface to PopelObjectCollection
|
||||
*/
|
||||
public function getArrayCopy($keyColumn = null, $usePrefix = false)
|
||||
{
|
||||
if (null === $keyColumn && false === $usePrefix) {
|
||||
return parent::getArrayCopy();
|
||||
} else {
|
||||
return $this->toArray($keyColumn, $usePrefix);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an associative array representation of the collection
|
||||
* The first parameter specifies the column to be used for the key,
|
||||
* And the seconf for the value.
|
||||
* <code>
|
||||
* $res = $coll->toKeyValue('Id', 'Name');
|
||||
* </code>
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toKeyValue($keyColumn, $valueColumn)
|
||||
{
|
||||
$ret = array();
|
||||
foreach ($this as $obj) {
|
||||
$ret[$obj[$keyColumn]] = $obj[$valueColumn];
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
protected function getWorkerObject()
|
||||
{
|
||||
if (null === $this->workerObject) {
|
||||
if ($this->model == '') {
|
||||
throw new PropelException('You must set the collection model before interacting with it');
|
||||
}
|
||||
$class = $this->getModel();
|
||||
$this->workerObject = new $class();
|
||||
}
|
||||
|
||||
return $this->workerObject;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
409
library/propel/runtime/lib/collection/PropelCollection.php
Normal file
409
library/propel/runtime/lib/collection/PropelCollection.php
Normal file
|
@ -0,0 +1,409 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class for iterating over a list of Propel elements
|
||||
* The collection keys must be integers - no associative array accepted
|
||||
*
|
||||
* @author Francois Zaninotto
|
||||
* @package propel.runtime.collection
|
||||
*/
|
||||
class PropelCollection extends ArrayObject implements Serializable
|
||||
{
|
||||
protected $model = '';
|
||||
protected $iterator;
|
||||
protected $formatter;
|
||||
|
||||
|
||||
// Generic Collection methods
|
||||
|
||||
/**
|
||||
* Get the data in the collection
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
return $this->getArrayCopy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the data in the collection
|
||||
*
|
||||
* @param array $data
|
||||
*/
|
||||
public function setData($data)
|
||||
{
|
||||
$this->exchangeArray($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the position of the internal pointer
|
||||
* This position can be later used in seek()
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getPosition()
|
||||
{
|
||||
return (int) $this->getInternalIterator()->key();
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the internal pointer to the beginning of the list
|
||||
* And get the first element in the collection
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getFirst()
|
||||
{
|
||||
$this->getInternalIterator()->rewind();
|
||||
return $this->getCurrent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the internal pointer is at the beginning of the list
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isFirst()
|
||||
{
|
||||
return $this->getPosition() == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the internal pointer backward
|
||||
* And get the previous element in the collection
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getPrevious()
|
||||
{
|
||||
$pos = $this->getPosition();
|
||||
if ($pos == 0) {
|
||||
return null;
|
||||
} else {
|
||||
$this->getInternalIterator()->seek($pos - 1);
|
||||
return $this->getCurrent();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current element in the collection
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getCurrent()
|
||||
{
|
||||
return $this->getInternalIterator()->current();
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the internal pointer forward
|
||||
* And get the next element in the collection
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getNext()
|
||||
{
|
||||
$this->getInternalIterator()->next();
|
||||
return $this->getCurrent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the internal pointer to the end of the list
|
||||
* And get the last element in the collection
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getLast()
|
||||
{
|
||||
$count = $this->count();
|
||||
if ($count == 0) {
|
||||
return null;
|
||||
} else {
|
||||
$this->getInternalIterator()->seek($count - 1);
|
||||
return $this->getCurrent();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the internal pointer is at the end of the list
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isLast()
|
||||
{
|
||||
$count = $this->count();
|
||||
if ($count == 0) {
|
||||
// empty list... so yes, this is the last
|
||||
return true;
|
||||
} else {
|
||||
return $this->getPosition() == $count - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the collection is empty
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isEmpty()
|
||||
{
|
||||
return $this->count() == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current index is an odd integer
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isOdd()
|
||||
{
|
||||
return (boolean) ($this->getInternalIterator()->key() % 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current index is an even integer
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isEven()
|
||||
{
|
||||
return !$this->isOdd();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an element from its key
|
||||
* Alias for ArrayObject::offsetGet()
|
||||
*
|
||||
* @param mixed $key
|
||||
*
|
||||
* @return mixed The element
|
||||
*/
|
||||
public function get($key)
|
||||
{
|
||||
if (!$this->offsetExists($key)) {
|
||||
throw new PropelException('Unknown key ' . $key);
|
||||
}
|
||||
return $this->offsetGet($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pops an element off the end of the collection
|
||||
*
|
||||
* @return mixed The popped element
|
||||
*/
|
||||
public function pop()
|
||||
{
|
||||
if ($this->count() == 0) {
|
||||
return null;
|
||||
}
|
||||
$ret = $this->getLast();
|
||||
$lastKey = $this->getInternalIterator()->key();
|
||||
$this->offsetUnset((string) $lastKey);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pops an element off the beginning of the collection
|
||||
*
|
||||
* @return mixed The popped element
|
||||
*/
|
||||
public function shift()
|
||||
{
|
||||
// the reindexing is complicated to deal with through the iterator
|
||||
// so let's use the simple solution
|
||||
$arr = $this->getArrayCopy();
|
||||
$ret = array_shift($arr);
|
||||
$this->exchangeArray($arr);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepend one or more elements to the beginning of the collection
|
||||
*
|
||||
* @param mixed $value the element to prepend
|
||||
*
|
||||
* @return int The number of new elements in the array
|
||||
*/
|
||||
public function prepend($value)
|
||||
{
|
||||
// the reindexing is complicated to deal with through the iterator
|
||||
// so let's use the simple solution
|
||||
$arr = $this->getArrayCopy();
|
||||
$ret = array_unshift($arr, $value);
|
||||
$this->exchangeArray($arr);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an element to the collection with the given key
|
||||
* Alias for ArrayObject::offsetSet()
|
||||
*
|
||||
* @param mixed $key
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function set($key, $value)
|
||||
{
|
||||
return $this->offsetSet($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a specified collection element
|
||||
* Alias for ArrayObject::offsetUnset()
|
||||
*
|
||||
* @param mixed $key
|
||||
*
|
||||
* @return mixed The removed element
|
||||
*/
|
||||
public function remove($key)
|
||||
{
|
||||
if (!$this->offsetExists($key)) {
|
||||
throw new PropelException('Unknown key ' . $key);
|
||||
}
|
||||
return $this->offsetUnset($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the collection
|
||||
*
|
||||
* @return array The previous collection
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
return $this->exchangeArray(array());
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not this collection contains a specified element
|
||||
*
|
||||
* @param mixed $element the element
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function contains($element)
|
||||
{
|
||||
return in_array($element, $this->getArrayCopy(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search an element in the collection
|
||||
*
|
||||
* @param mixed $element
|
||||
*
|
||||
* @return mixed Returns the key for the element if it is found in the collection, FALSE otherwise
|
||||
*/
|
||||
public function search($element)
|
||||
{
|
||||
return array_search($element, $this->getArrayCopy(), true);
|
||||
}
|
||||
|
||||
// Serializable interface
|
||||
|
||||
public function serialize()
|
||||
{
|
||||
$repr = array(
|
||||
'data' => $this->getArrayCopy(),
|
||||
'model' => $this->model,
|
||||
);
|
||||
return serialize($repr);
|
||||
}
|
||||
|
||||
public function unserialize($data)
|
||||
{
|
||||
$repr = unserialize($data);
|
||||
$this->exchangeArray($repr['data']);
|
||||
$this->model = $repr['model'];
|
||||
}
|
||||
|
||||
// IteratorAggregate method
|
||||
|
||||
/**
|
||||
* Overrides ArrayObject::getIterator() to save the iterator object
|
||||
* for internal use e.g. getNext(), isOdd(), etc.
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
$this->iterator = new ArrayIterator($this);
|
||||
return $this->iterator;
|
||||
}
|
||||
|
||||
public function getInternalIterator()
|
||||
{
|
||||
if (null === $this->iterator) {
|
||||
return $this->getIterator();
|
||||
}
|
||||
return $this->iterator;
|
||||
}
|
||||
|
||||
// Propel collection methods
|
||||
|
||||
/**
|
||||
* Set the model of the elements in the collection
|
||||
*
|
||||
* @param string $model Name of the Propel object classes stored in the collection
|
||||
*/
|
||||
public function setModel($model)
|
||||
{
|
||||
$this->model = $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the model of the elements in the collection
|
||||
*
|
||||
* @return string Name of the Propel object class stored in the collection
|
||||
*/
|
||||
public function getModel()
|
||||
{
|
||||
return $this->model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the peer class of the elements in the collection
|
||||
*
|
||||
* @return string Name of the Propel peer class stored in the collection
|
||||
*/
|
||||
public function getPeerClass()
|
||||
{
|
||||
if ($this->model == '') {
|
||||
throw new PropelException('You must set the collection model before interacting with it');
|
||||
}
|
||||
return constant($this->getModel() . '::PEER');
|
||||
}
|
||||
|
||||
public function setFormatter(PropelFormatter $formatter)
|
||||
{
|
||||
$this->formatter = $formatter;
|
||||
}
|
||||
|
||||
public function getFormatter()
|
||||
{
|
||||
return $this->formatter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a connection object for the database containing the elements of the collection
|
||||
*
|
||||
* @param string $type The connection type (Propel::CONNECTION_READ by default; can be Propel::connection_WRITE)
|
||||
*
|
||||
* @return PropelPDO a connection object
|
||||
*/
|
||||
public function getConnection($type = Propel::CONNECTION_READ)
|
||||
{
|
||||
$databaseName = constant($this->getPeerClass() . '::DATABASE_NAME');
|
||||
|
||||
return Propel::getConnection($databaseName, $type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
249
library/propel/runtime/lib/collection/PropelObjectCollection.php
Normal file
249
library/propel/runtime/lib/collection/PropelObjectCollection.php
Normal file
|
@ -0,0 +1,249 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class for iterating over a list of Propel objects
|
||||
*
|
||||
* @author Francois Zaninotto
|
||||
* @package propel.runtime.collection
|
||||
*/
|
||||
class PropelObjectCollection extends PropelCollection
|
||||
{
|
||||
|
||||
/**
|
||||
* Save all the elements in the collection
|
||||
*/
|
||||
public function save($con = null)
|
||||
{
|
||||
if (null === $con) {
|
||||
$con = $this->getConnection(Propel::CONNECTION_WRITE);
|
||||
}
|
||||
$con->beginTransaction();
|
||||
try {
|
||||
foreach ($this as $element) {
|
||||
$element->save($con);
|
||||
}
|
||||
$con->commit();
|
||||
} catch (PropelException $e) {
|
||||
$con->rollback();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all the elements in the collection
|
||||
*/
|
||||
public function delete($con = null)
|
||||
{
|
||||
if (null === $con) {
|
||||
$con = $this->getConnection(Propel::CONNECTION_WRITE);
|
||||
}
|
||||
$con->beginTransaction();
|
||||
try {
|
||||
foreach ($this as $element) {
|
||||
$element->delete($con);
|
||||
}
|
||||
$con->commit();
|
||||
} catch (PropelException $e) {
|
||||
$con->rollback();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of the primary keys of all the objects in the collection
|
||||
*
|
||||
* @return array The list of the primary keys of the collection
|
||||
*/
|
||||
public function getPrimaryKeys($usePrefix = true)
|
||||
{
|
||||
$ret = array();
|
||||
foreach ($this as $key => $obj) {
|
||||
$key = $usePrefix ? ($this->getModel() . '_' . $key) : $key;
|
||||
$ret[$key]= $obj->getPrimaryKey();
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the collection from an array
|
||||
* Each object is populated from an array and the result is stored
|
||||
* Does not empty the collection before adding the data from the array
|
||||
*
|
||||
* @param array $arr
|
||||
*/
|
||||
public function fromArray($arr)
|
||||
{
|
||||
$class = $this->getModel();
|
||||
foreach ($arr as $element) {
|
||||
$obj = new $class();
|
||||
$obj->fromArray($element);
|
||||
$this->append($obj);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array representation of the collection
|
||||
* Each object is turned into an array and the result is returned
|
||||
*
|
||||
* @param string $keyColumn If null, the returned array uses an incremental index.
|
||||
* Otherwise, the array is indexed using the specified column
|
||||
* @param boolean $usePrefix If true, the returned array prefixes keys
|
||||
* with the model class name ('Article_0', 'Article_1', etc).
|
||||
*
|
||||
* <code>
|
||||
* $bookCollection->toArray();
|
||||
* array(
|
||||
* 0 => array('Id' => 123, 'Title' => 'War And Peace'),
|
||||
* 1 => array('Id' => 456, 'Title' => 'Don Juan'),
|
||||
* )
|
||||
* $bookCollection->toArray('Id');
|
||||
* array(
|
||||
* 123 => array('Id' => 123, 'Title' => 'War And Peace'),
|
||||
* 456 => array('Id' => 456, 'Title' => 'Don Juan'),
|
||||
* )
|
||||
* $bookCollection->toArray(null, true);
|
||||
* array(
|
||||
* 'Book_0' => array('Id' => 123, 'Title' => 'War And Peace'),
|
||||
* 'Book_1' => array('Id' => 456, 'Title' => 'Don Juan'),
|
||||
* )
|
||||
* </code>
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($keyColumn = null, $usePrefix = false)
|
||||
{
|
||||
$ret = array();
|
||||
$keyGetterMethod = 'get' . $keyColumn;
|
||||
foreach ($this as $key => $obj) {
|
||||
$key = null === $keyColumn ? $key : $obj->$keyGetterMethod();
|
||||
$key = $usePrefix ? ($this->getModel() . '_' . $key) : $key;
|
||||
$ret[$key] = $obj->toArray();
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array representation of the collection
|
||||
*
|
||||
* @param string $keyColumn If null, the returned array uses an incremental index.
|
||||
* Otherwise, the array is indexed using the specified column
|
||||
* @param boolean $usePrefix If true, the returned array prefixes keys
|
||||
* with the model class name ('Article_0', 'Article_1', etc).
|
||||
*
|
||||
* <code>
|
||||
* $bookCollection->getArrayCopy();
|
||||
* array(
|
||||
* 0 => $book0,
|
||||
* 1 => $book1,
|
||||
* )
|
||||
* $bookCollection->getArrayCopy('Id');
|
||||
* array(
|
||||
* 123 => $book0,
|
||||
* 456 => $book1,
|
||||
* )
|
||||
* $bookCollection->getArrayCopy(null, true);
|
||||
* array(
|
||||
* 'Book_0' => $book0,
|
||||
* 'Book_1' => $book1,
|
||||
* )
|
||||
* </code>
|
||||
* @return array
|
||||
*/
|
||||
public function getArrayCopy($keyColumn = null, $usePrefix = false)
|
||||
{
|
||||
if (null === $keyColumn && false === $usePrefix) {
|
||||
return parent::getArrayCopy();
|
||||
}
|
||||
$ret = array();
|
||||
$keyGetterMethod = 'get' . $keyColumn;
|
||||
foreach ($this as $key => $obj) {
|
||||
$key = null === $keyColumn ? $key : $obj->$keyGetterMethod();
|
||||
$key = $usePrefix ? ($this->getModel() . '_' . $key) : $key;
|
||||
$ret[$key] = $obj;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an associative array representation of the collection
|
||||
* The first parameter specifies the column to be used for the key,
|
||||
* And the seconf for the value.
|
||||
* <code>
|
||||
* $res = $coll->toKeyValue('Id', 'Name');
|
||||
* </code>
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toKeyValue($keyColumn = 'PrimaryKey', $valueColumn = null)
|
||||
{
|
||||
$ret = array();
|
||||
$keyGetterMethod = 'get' . $keyColumn;
|
||||
$valueGetterMethod = (null === $valueColumn) ? '__toString' : ('get' . $valueColumn);
|
||||
foreach ($this as $obj) {
|
||||
$ret[$obj->$keyGetterMethod()] = $obj->$valueGetterMethod();
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes an additional query to populate the objects related to the collection objects
|
||||
* by a certain relation
|
||||
*
|
||||
* @param string $relation Relation name (e.g. 'Book')
|
||||
* @param Criteria $criteria Optional Criteria object to filter the related object collection
|
||||
* @param PropelPDO $con Optional connection object
|
||||
*
|
||||
* @return PropelObjectCollection the list of related objects
|
||||
*/
|
||||
public function populateRelation($relation, $criteria = null, $con = null)
|
||||
{
|
||||
if (!Propel::isInstancePoolingEnabled()) {
|
||||
throw new PropelException('populateRelation() needs instance pooling to be enabled prior to populating the collection');
|
||||
}
|
||||
$relationMap = $this->getFormatter()->getTableMap()->getRelation($relation);
|
||||
$symRelationMap = $relationMap->getSymmetricalRelation();
|
||||
|
||||
// query the db for the related objects
|
||||
$useMethod = 'use' . $symRelationMap->getName() . 'Query';
|
||||
$query = PropelQuery::from($relationMap->getRightTable()->getPhpName());
|
||||
if (null !== $criteria) {
|
||||
$query->mergeWith($criteria);
|
||||
}
|
||||
$relatedObjects = $query
|
||||
->$useMethod()
|
||||
->filterByPrimaryKeys($this->getPrimaryKeys())
|
||||
->endUse()
|
||||
->find($con);
|
||||
|
||||
// associate the related objects to the main objects
|
||||
if ($relationMap->getType() == RelationMap::ONE_TO_MANY) {
|
||||
$getMethod = 'get' . $symRelationMap->getName();
|
||||
$addMethod = 'add' . $relationMap->getName();
|
||||
foreach ($relatedObjects as $object) {
|
||||
$mainObj = $object->$getMethod(); // instance pool is used here to avoid a query
|
||||
$mainObj->$addMethod($object);
|
||||
}
|
||||
} elseif ($relationMap->getType() == RelationMap::MANY_TO_ONE) {
|
||||
// nothing to do; the instance pool will catch all calls to getRelatedObject()
|
||||
// and return the object in memory
|
||||
} else {
|
||||
throw new PropelException('populateRelation() does not support this relation type');
|
||||
}
|
||||
|
||||
return $relatedObjects;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,151 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class for iterating over a statement and returning one Propel object at a time
|
||||
*
|
||||
* @author Francois Zaninotto
|
||||
* @package propel.runtime.collection
|
||||
*/
|
||||
class PropelOnDemandCollection extends PropelCollection
|
||||
{
|
||||
protected
|
||||
$iterator,
|
||||
$currentRow,
|
||||
$currentKey = -1,
|
||||
$isValid = null;
|
||||
|
||||
public function initIterator(PropelFormatter $formatter, PDOStatement $stmt)
|
||||
{
|
||||
$this->iterator = new PropelOnDemandIterator($formatter, $stmt);
|
||||
}
|
||||
|
||||
// IteratorAggregate Interface
|
||||
|
||||
public function getIterator()
|
||||
{
|
||||
return $this->iterator;
|
||||
}
|
||||
|
||||
// ArrayAccess Interface
|
||||
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
if ($offset == $this->currentKey) {
|
||||
return true;
|
||||
}
|
||||
throw new PropelException('The On Demand Collection does not allow acces by offset');
|
||||
}
|
||||
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
if ($offset == $this->currentKey) {
|
||||
return $this->currentRow;
|
||||
}
|
||||
throw new PropelException('The On Demand Collection does not allow acces by offset');
|
||||
}
|
||||
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
throw new PropelException('The On Demand Collection is read only');
|
||||
}
|
||||
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
throw new PropelException('The On Demand Collection is read only');
|
||||
}
|
||||
|
||||
// Serializable Interface
|
||||
|
||||
public function serialize()
|
||||
{
|
||||
throw new PropelException('The On Demand Collection cannot be serialized');
|
||||
}
|
||||
|
||||
public function unserialize($data)
|
||||
{
|
||||
throw new PropelException('The On Demand Collection cannot be serialized');
|
||||
}
|
||||
|
||||
// Countable Interface
|
||||
|
||||
/**
|
||||
* Returns the number of rows in the resultset
|
||||
* Warning: this number is inaccurate for most databases. Do not rely on it for a portable application.
|
||||
*
|
||||
* @return int number of results
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return $this->iterator->count();
|
||||
}
|
||||
|
||||
// ArrayObject methods
|
||||
|
||||
public function append($value)
|
||||
{
|
||||
throw new PropelException('The On Demand Collection is read only');
|
||||
}
|
||||
|
||||
public function prepend($value)
|
||||
{
|
||||
throw new PropelException('The On Demand Collection is read only');
|
||||
}
|
||||
|
||||
public function asort()
|
||||
{
|
||||
throw new PropelException('The On Demand Collection is read only');
|
||||
}
|
||||
|
||||
public function exchangeArray($input)
|
||||
{
|
||||
throw new PropelException('The On Demand Collection is read only');
|
||||
}
|
||||
|
||||
public function getArrayCopy()
|
||||
{
|
||||
throw new PropelException('The On Demand Collection does not allow acces by offset');
|
||||
}
|
||||
|
||||
public function getFlags()
|
||||
{
|
||||
throw new PropelException('The On Demand Collection does not allow acces by offset');
|
||||
}
|
||||
|
||||
public function ksort()
|
||||
{
|
||||
throw new PropelException('The On Demand Collection is read only');
|
||||
}
|
||||
|
||||
public function natcasesort()
|
||||
{
|
||||
throw new PropelException('The On Demand Collection is read only');
|
||||
}
|
||||
|
||||
public function natsort()
|
||||
{
|
||||
throw new PropelException('The On Demand Collection is read only');
|
||||
}
|
||||
|
||||
public function setFlags($flags)
|
||||
{
|
||||
throw new PropelException('The On Demand Collection does not allow acces by offset');
|
||||
}
|
||||
|
||||
public function uasort($cmp_function)
|
||||
{
|
||||
throw new PropelException('The On Demand Collection is read only');
|
||||
}
|
||||
|
||||
public function uksort($cmp_function)
|
||||
{
|
||||
throw new PropelException('The On Demand Collection is read only');
|
||||
}
|
||||
}
|
118
library/propel/runtime/lib/collection/PropelOnDemandIterator.php
Executable file
118
library/propel/runtime/lib/collection/PropelOnDemandIterator.php
Executable file
|
@ -0,0 +1,118 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class for iterating over a statement and returning one Propel object at a time
|
||||
*
|
||||
* @author Francois Zaninotto
|
||||
* @package propel.runtime.collection
|
||||
*/
|
||||
class PropelOnDemandIterator implements Iterator
|
||||
{
|
||||
protected
|
||||
$formatter,
|
||||
$stmt,
|
||||
$currentRow,
|
||||
$currentKey = -1,
|
||||
$isValid = null,
|
||||
$enableInstancePoolingOnFinish = false;
|
||||
|
||||
public function __construct(PropelFormatter $formatter, PDOStatement $stmt)
|
||||
{
|
||||
$this->formatter = $formatter;
|
||||
$this->stmt = $stmt;
|
||||
$this->enableInstancePoolingOnFinish = Propel::disableInstancePooling();
|
||||
}
|
||||
|
||||
public function closeCursor()
|
||||
{
|
||||
$this->stmt->closeCursor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of rows in the resultset
|
||||
* Warning: this number is inaccurate for most databases. Do not rely on it for a portable application.
|
||||
*
|
||||
* @return int number of results
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return $this->stmt->rowCount();
|
||||
}
|
||||
|
||||
// Iterator Interface
|
||||
|
||||
/**
|
||||
* Gets the current Model object in the collection
|
||||
* This is where the hydration takes place.
|
||||
*
|
||||
* @see PropelObjectFormatter::getAllObjectsFromRow()
|
||||
*
|
||||
* @return BaseObject
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return $this->formatter->getAllObjectsFromRow($this->currentRow);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current key in the iterator
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return $this->currentKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Advances the curesor in the statement
|
||||
* Closes the cursor if the end of the statement is reached
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
$this->currentRow = $this->stmt->fetch(PDO::FETCH_NUM);
|
||||
$this->currentKey++;
|
||||
$this->isValid = (boolean) $this->currentRow;
|
||||
if (!$this->isValid) {
|
||||
$this->closeCursor();
|
||||
if ($this->enableInstancePoolingOnFinish) {
|
||||
Propel::enableInstancePooling();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the iterator by advancing to the first position
|
||||
* This method can only be called once (this is a NoRewindIterator)
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
// check that the hydration can begin
|
||||
if (null === $this->formatter) {
|
||||
throw new PropelException('The On Demand collection requires a formatter. Add it by calling setFormatter()');
|
||||
}
|
||||
if (null === $this->stmt) {
|
||||
throw new PropelException('The On Demand collection requires a statement. Add it by calling setStatement()');
|
||||
}
|
||||
if (null !== $this->isValid) {
|
||||
throw new PropelException('The On Demand collection can only be iterated once');
|
||||
}
|
||||
|
||||
// initialize the current row and key
|
||||
$this->next();
|
||||
}
|
||||
|
||||
public function valid()
|
||||
{
|
||||
return $this->isValid;
|
||||
}
|
||||
|
||||
}
|
159
library/propel/runtime/lib/config/PropelConfiguration.php
Normal file
159
library/propel/runtime/lib/config/PropelConfiguration.php
Normal file
|
@ -0,0 +1,159 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* PropelConfiguration is a container for all Propel's configuration data.
|
||||
*
|
||||
* PropelConfiguration implements ArrayAccess interface so the configuration
|
||||
* can be accessed as an array or using a simple getter and setter. The whole
|
||||
* configuration can also be retrieved as a nested arrays, flat array or as a
|
||||
* PropelConfiguration instance.
|
||||
*
|
||||
* @author Veikko Mäkinen <veikko@veikko.fi>
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.config
|
||||
*/
|
||||
class PropelConfiguration implements ArrayAccess
|
||||
{
|
||||
const TYPE_ARRAY = 1;
|
||||
|
||||
const TYPE_ARRAY_FLAT = 2;
|
||||
|
||||
const TYPE_OBJECT = 3;
|
||||
|
||||
/**
|
||||
* @var array An array of parameters
|
||||
*/
|
||||
protected $parameters = array();
|
||||
|
||||
/**
|
||||
* Construct a new configuration container
|
||||
*
|
||||
* @param array $parameters
|
||||
*/
|
||||
public function __construct(array $parameters = array())
|
||||
{
|
||||
$this->parameters = $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see http://www.php.net/ArrayAccess
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return array_key_exists($offset, $this->parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see http://www.php.net/ArrayAccess
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->parameter[$offset] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see http://www.php.net/ArrayAccess
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->parameters[$offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* @see http://www.php.net/ArrayAccess
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->parameters[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get parameter value from the container
|
||||
*
|
||||
* @param string $name Parameter name
|
||||
* @param mixed $default Default value to be used if the
|
||||
* requested value is not found
|
||||
* @return mixed Parameter value or the default
|
||||
*/
|
||||
public function getParameter($name, $default = null)
|
||||
{
|
||||
$ret = $this->parameters;
|
||||
$parts = explode('.', $name); //name.space.name
|
||||
while ($part = array_shift($parts)) {
|
||||
if (isset($ret[$part])) {
|
||||
$ret = $ret[$part];
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a value to the container
|
||||
*
|
||||
* @param string $name Configuration item name (name.space.name)
|
||||
* @param mixed $value Value to be stored
|
||||
*/
|
||||
public function setParameter($name, $value)
|
||||
{
|
||||
$param = &$this->parameters;
|
||||
$parts = explode('.', $name); //name.space.name
|
||||
while ($part = array_shift($parts)) {
|
||||
$param = &$param[$part];
|
||||
}
|
||||
$param = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param int $type
|
||||
* @return mixed
|
||||
*/
|
||||
public function getParameters($type = PropelConfiguration::TYPE_ARRAY)
|
||||
{
|
||||
switch ($type) {
|
||||
case PropelConfiguration::TYPE_ARRAY:
|
||||
return $this->parameters;
|
||||
case PropelConfiguration::TYPE_ARRAY_FLAT:
|
||||
return $this->toFlatArray();
|
||||
case PropelConfiguration::TYPE_OBJECT:
|
||||
return $this;
|
||||
default:
|
||||
throw new PropelException('Unknown configuration type: '. var_export($type, true));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the configuration as a flat array. ($array['name.space.item'] = 'value')
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function toFlatArray()
|
||||
{
|
||||
$result = array();
|
||||
$it = new PropelConfigurationIterator(new RecursiveArrayIterator($this->parameters), RecursiveIteratorIterator::SELF_FIRST);
|
||||
foreach($it as $key => $value) {
|
||||
$ns = $it->getDepth() ? $it->getNamespace() . '.'. $key : $key;
|
||||
if ($it->getNodeType() == PropelConfigurationIterator::NODE_ITEM) {
|
||||
$result[$ns] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,103 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* PropelConfigurationIterator is used internally by PropelConfiguration to
|
||||
* build a flat array from nesting configuration arrays.
|
||||
*
|
||||
* @author Veikko Mäkinen <veikko@veikko.fi>
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.config
|
||||
*/
|
||||
class PropelConfigurationIterator extends RecursiveIteratorIterator
|
||||
{
|
||||
/**
|
||||
* Node is a parent node
|
||||
*/
|
||||
const NODE_PARENT = 0;
|
||||
|
||||
/**
|
||||
* Node is an actual configuration item
|
||||
*/
|
||||
const NODE_ITEM = 1;
|
||||
|
||||
/**
|
||||
* Namespace stack when recursively iterating the configuration tree
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $namespaceStack = array();
|
||||
|
||||
/**
|
||||
* Current node type. Possible values: null (undefined), self::NODE_PARENT or self::NODE_ITEM
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $nodeType = null;
|
||||
|
||||
/**
|
||||
* Get current namespace
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return implode('.', $this->namespaceStack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current node type.
|
||||
*
|
||||
* @see http://www.php.net/RecursiveIteratorIterator
|
||||
* @return int
|
||||
* - null (undefined)
|
||||
* - self::NODE_PARENT
|
||||
* - self::NODE_ITEM
|
||||
*/
|
||||
public function getNodeType()
|
||||
{
|
||||
return $this->nodeType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current element
|
||||
*
|
||||
* @see http://www.php.net/RecursiveIteratorIterator
|
||||
* @return mixed
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
$current = parent::current();
|
||||
if (is_array($current)) {
|
||||
$this->namespaceStack[] = $this->key();
|
||||
$this->nodeType = self::NODE_PARENT;
|
||||
}
|
||||
else {
|
||||
$this->nodeType = self::NODE_ITEM;
|
||||
}
|
||||
|
||||
return $current;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after current child iterator is invalid and right before it gets destructed.
|
||||
*
|
||||
* @see http://www.php.net/RecursiveIteratorIterator
|
||||
*/
|
||||
public function endChildren()
|
||||
{
|
||||
if ($this->namespaceStack) {
|
||||
array_pop($this->namespaceStack);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
111
library/propel/runtime/lib/connection/DebugPDO.php
Normal file
111
library/propel/runtime/lib/connection/DebugPDO.php
Normal file
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* PDO connection subclass that provides some basic support for query counting and logging.
|
||||
*
|
||||
* This class is ONLY intended for development use. This class is also a work in-progress
|
||||
* and, as such, it should be expected that this class' API may change.
|
||||
*
|
||||
* The following runtime configuration items affect the behaviour of this class:
|
||||
*
|
||||
* - debugpdo.logging.enabled (default: true)
|
||||
* Should any logging take place
|
||||
*
|
||||
* - debugpdo.logging.innerglue (default: ": ")
|
||||
* String to use for combining the title of a detail and its value
|
||||
*
|
||||
* - debugpdo.logging.outerglue (default: " | ")
|
||||
* String to use for combining details together on a log line
|
||||
*
|
||||
* - debugpdo.logging.realmemoryusage (default: false)
|
||||
* Parameter to memory_get_usage() and memory_get_peak_usage() calls
|
||||
*
|
||||
* - debugpdo.logging.methods (default: DebugPDO::$defaultLogMethods)
|
||||
* An array of method names ("Class::method") to be included in method call logging
|
||||
*
|
||||
* - debugpdo.logging.onlyslow (default: false)
|
||||
* Suppress logging of non-slow queries.
|
||||
*
|
||||
* - debugpdo.logging.details.slow.enabled (default: false)
|
||||
* Enables flagging of slow method calls
|
||||
*
|
||||
* - debugpdo.logging.details.slow.threshold (default: 0.1)
|
||||
* Method calls taking more seconds than this threshold are considered slow
|
||||
*
|
||||
* - debugpdo.logging.details.time.enabled (default: false)
|
||||
* Enables logging of method execution times
|
||||
*
|
||||
* - debugpdo.logging.details.time.precision (default: 3)
|
||||
* Determines the precision of the execution time logging
|
||||
*
|
||||
* - debugpdo.logging.details.time.pad (default: 10)
|
||||
* How much horizontal space to reserve for the execution time on a log line
|
||||
*
|
||||
* - debugpdo.logging.details.mem.enabled (default: false)
|
||||
* Enables logging of the instantaneous PHP memory consumption
|
||||
*
|
||||
* - debugpdo.logging.details.mem.precision (default: 1)
|
||||
* Determines the precision of the memory consumption logging
|
||||
*
|
||||
* - debugpdo.logging.details.mem.pad (default: 9)
|
||||
* How much horizontal space to reserve for the memory consumption on a log line
|
||||
*
|
||||
* - debugpdo.logging.details.memdelta.enabled (default: false)
|
||||
* Enables logging differences in memory consumption before and after the method call
|
||||
*
|
||||
* - debugpdo.logging.details.memdelta.precision (default: 1)
|
||||
* Determines the precision of the memory difference logging
|
||||
*
|
||||
* - debugpdo.logging.details.memdelta.pad (default: 10)
|
||||
* How much horizontal space to reserve for the memory difference on a log line
|
||||
*
|
||||
* - debugpdo.logging.details.mempeak.enabled (default: false)
|
||||
* Enables logging the peak memory consumption thus far by the currently executing PHP script
|
||||
*
|
||||
* - debugpdo.logging.details.mempeak.precision (default: 1)
|
||||
* Determines the precision of the memory peak logging
|
||||
*
|
||||
* - debugpdo.logging.details.mempeak.pad (default: 9)
|
||||
* How much horizontal space to reserve for the memory peak on a log line
|
||||
*
|
||||
* - debugpdo.logging.details.querycount.enabled (default: false)
|
||||
* Enables logging of the number of queries performed by the DebugPDO instance thus far
|
||||
*
|
||||
* - debugpdo.logging.details.querycount.pad (default: 2)
|
||||
* How much horizontal space to reserve for the query count on a log line
|
||||
*
|
||||
* - debugpdo.logging.details.method.enabled (default: false)
|
||||
* Enables logging of the name of the method call
|
||||
*
|
||||
* - debugpdo.logging.details.method.pad (default: 28)
|
||||
* How much horizontal space to reserve for the method name on a log line
|
||||
*
|
||||
* The order in which the logging details are enabled is significant, since it determines the order in
|
||||
* which they will appear in the log file.
|
||||
*
|
||||
* @example // Enable simple query profiling, flagging calls taking over 1.5 seconds as slow:
|
||||
* $config = Propel::getConfiguration(PropelConfiguration::TYPE_OBJECT);
|
||||
* $config->setParameter('debugpdo.logging.details.slow.enabled', true);
|
||||
* $config->setParameter('debugpdo.logging.details.slow.threshold', 1.5);
|
||||
* $config->setParameter('debugpdo.logging.details.time.enabled', true);
|
||||
*
|
||||
* @author Francois Zaninotto
|
||||
* @author Cameron Brunner <cameron.brunner@gmail.com>
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @author Christian Abegg <abegg.ch@gmail.com>
|
||||
* @author Jarno Rantanen <jarno.rantanen@tkk.fi>
|
||||
* @since 2006-09-22
|
||||
* @package propel.runtime.connection
|
||||
*/
|
||||
class DebugPDO extends PropelPDO
|
||||
{
|
||||
public $useDebug = true;
|
||||
}
|
122
library/propel/runtime/lib/connection/DebugPDOStatement.php
Normal file
122
library/propel/runtime/lib/connection/DebugPDOStatement.php
Normal file
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* PDOStatement that provides some enhanced functionality needed by Propel.
|
||||
*
|
||||
* Simply adds the ability to count the number of queries executed and log the queries/method calls.
|
||||
*
|
||||
* @author Oliver Schonrock <oliver@realtsp.com>
|
||||
* @author Jarno Rantanen <jarno.rantanen@tkk.fi>
|
||||
* @since 2007-07-12
|
||||
* @package propel.runtime.connection
|
||||
*/
|
||||
class DebugPDOStatement extends PDOStatement
|
||||
{
|
||||
|
||||
/**
|
||||
* The PDO connection from which this instance was created.
|
||||
*
|
||||
* @var PropelPDO
|
||||
*/
|
||||
protected $pdo;
|
||||
|
||||
/**
|
||||
* Hashmap for resolving the PDO::PARAM_* class constants to their human-readable names.
|
||||
*
|
||||
* This is only used in logging the binding of variables.
|
||||
*
|
||||
* @see self::bindValue()
|
||||
* @var array
|
||||
*/
|
||||
protected static $typeMap = array(
|
||||
PDO::PARAM_BOOL => "PDO::PARAM_BOOL",
|
||||
PDO::PARAM_INT => "PDO::PARAM_INT",
|
||||
PDO::PARAM_STR => "PDO::PARAM_STR",
|
||||
PDO::PARAM_LOB => "PDO::PARAM_LOB",
|
||||
PDO::PARAM_NULL => "PDO::PARAM_NULL",
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array The values that have been bound
|
||||
*/
|
||||
protected $boundValues = array();
|
||||
|
||||
/**
|
||||
* Construct a new statement class with reference to main DebugPDO object from
|
||||
* which this instance was created.
|
||||
*
|
||||
* @param DebugPDO $pdo Reference to the parent PDO instance.
|
||||
*/
|
||||
protected function __construct(PropelPDO $pdo)
|
||||
{
|
||||
$this->pdo = $pdo;
|
||||
}
|
||||
|
||||
public function getExecutedQueryString()
|
||||
{
|
||||
$sql = $this->queryString;
|
||||
$matches = array();
|
||||
if (preg_match_all('/(:p[0-9]+\b)/', $sql, $matches)) {
|
||||
$size = count($matches[1]);
|
||||
for ($i = $size-1; $i >= 0; $i--) {
|
||||
$pos = $matches[1][$i];
|
||||
$sql = str_replace($pos, $this->boundValues[$pos], $sql);
|
||||
}
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a prepared statement. Returns a boolean value indicating success.
|
||||
*
|
||||
* Overridden for query counting and logging.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function execute($input_parameters = null)
|
||||
{
|
||||
$debug = $this->pdo->getDebugSnapshot();
|
||||
$return = parent::execute($input_parameters);
|
||||
|
||||
$sql = $this->getExecutedQueryString();
|
||||
$this->pdo->log($sql, null, __METHOD__, $debug);
|
||||
$this->pdo->setLastExecutedQuery($sql);
|
||||
$this->pdo->incrementQueryCount();
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds a value to a corresponding named or question mark placeholder in the SQL statement
|
||||
* that was use to prepare the statement. Returns a boolean value indicating success.
|
||||
*
|
||||
* @param int $pos Parameter identifier (for determining what to replace in the query).
|
||||
* @param mixed $value The value to bind to the parameter.
|
||||
* @param int $type Explicit data type for the parameter using the PDO::PARAM_* constants. Defaults to PDO::PARAM_STR.
|
||||
* @return boolean
|
||||
*/
|
||||
public function bindValue($pos, $value, $type = PDO::PARAM_STR)
|
||||
{
|
||||
$debug = $this->pdo->getDebugSnapshot();
|
||||
$typestr = isset(self::$typeMap[$type]) ? self::$typeMap[$type] : '(default)';
|
||||
$return = parent::bindValue($pos, $value, $type);
|
||||
$valuestr = $type == PDO::PARAM_LOB ? '[LOB value]' : var_export($value, true);
|
||||
$msg = "Binding $valuestr at position $pos w/ PDO type $typestr";
|
||||
|
||||
$this->boundValues[$pos] = $valuestr;
|
||||
|
||||
$this->pdo->log($msg, null, __METHOD__, $debug);
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
}
|
716
library/propel/runtime/lib/connection/PropelPDO.php
Normal file
716
library/propel/runtime/lib/connection/PropelPDO.php
Normal file
|
@ -0,0 +1,716 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* PDO connection subclass that provides the basic fixes to PDO that are required by Propel.
|
||||
*
|
||||
* This class was designed to work around the limitation in PDO where attempting to begin
|
||||
* a transaction when one has already been begun will trigger a PDOException. Propel
|
||||
* relies on the ability to create nested transactions, even if the underlying layer
|
||||
* simply ignores these (because it doesn't support nested transactions).
|
||||
*
|
||||
* The changes that this class makes to the underlying API include the addition of the
|
||||
* getNestedTransactionDepth() and isInTransaction() and the fact that beginTransaction()
|
||||
* will no longer throw a PDOException (or trigger an error) if a transaction is already
|
||||
* in-progress.
|
||||
*
|
||||
* @author Cameron Brunner <cameron.brunner@gmail.com>
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @author Christian Abegg <abegg.ch@gmail.com>
|
||||
* @since 2006-09-22
|
||||
* @package propel.runtime.connection
|
||||
*/
|
||||
class PropelPDO extends PDO
|
||||
{
|
||||
|
||||
/**
|
||||
* Attribute to use to set whether to cache prepared statements.
|
||||
*/
|
||||
const PROPEL_ATTR_CACHE_PREPARES = -1;
|
||||
|
||||
const DEFAULT_SLOW_THRESHOLD = 0.1;
|
||||
const DEFAULT_ONLYSLOW_ENABLED = false;
|
||||
|
||||
/**
|
||||
* The current transaction depth.
|
||||
* @var int
|
||||
*/
|
||||
protected $nestedTransactionCount = 0;
|
||||
|
||||
/**
|
||||
* Cache of prepared statements (PDOStatement) keyed by md5 of SQL.
|
||||
*
|
||||
* @var array [md5(sql) => PDOStatement]
|
||||
*/
|
||||
protected $preparedStatements = array();
|
||||
|
||||
/**
|
||||
* Whether to cache prepared statements.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $cachePreparedStatements = false;
|
||||
|
||||
/**
|
||||
* Whether the final commit is possible
|
||||
* Is false if a nested transaction is rolled back
|
||||
*/
|
||||
protected $isUncommitable = false;
|
||||
|
||||
/**
|
||||
* Count of queries performed.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $queryCount = 0;
|
||||
|
||||
/**
|
||||
* SQL code of the latest performed query.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $lastExecutedQuery;
|
||||
|
||||
/**
|
||||
* Whether or not the debug is enabled
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public $useDebug = false;
|
||||
|
||||
/**
|
||||
* Configured BasicLogger (or compatible) logger.
|
||||
*
|
||||
* @var BasicLogger
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* The log level to use for logging.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $logLevel = Propel::LOG_DEBUG;
|
||||
|
||||
/**
|
||||
* The default value for runtime config item "debugpdo.logging.methods".
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $defaultLogMethods = array(
|
||||
'PropelPDO::exec',
|
||||
'PropelPDO::query',
|
||||
'DebugPDOStatement::execute',
|
||||
);
|
||||
|
||||
/**
|
||||
* Creates a PropelPDO instance representing a connection to a database.
|
||||
*.
|
||||
* If so configured, specifies a custom PDOStatement class and makes an entry
|
||||
* to the log with the state of this object just after its initialization.
|
||||
* Add PropelPDO::__construct to $defaultLogMethods to see this message
|
||||
*
|
||||
* @param string $dsn Connection DSN.
|
||||
* @param string $username (optional) The user name for the DSN string.
|
||||
* @param string $password (optional) The password for the DSN string.
|
||||
* @param array $driver_options (optional) A key=>value array of driver-specific connection options.
|
||||
* @throws PDOException if there is an error during connection initialization.
|
||||
*/
|
||||
public function __construct($dsn, $username = null, $password = null, $driver_options = array())
|
||||
{
|
||||
if ($this->useDebug) {
|
||||
$debug = $this->getDebugSnapshot();
|
||||
}
|
||||
|
||||
parent::__construct($dsn, $username, $password, $driver_options);
|
||||
|
||||
if ($this->useDebug) {
|
||||
$this->configureStatementClass('DebugPDOStatement', $suppress = true);
|
||||
$this->log('Opening connection', null, __METHOD__, $debug);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current transaction depth.
|
||||
* @return int
|
||||
*/
|
||||
public function getNestedTransactionCount()
|
||||
{
|
||||
return $this->nestedTransactionCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current transaction depth.
|
||||
* @param int $v The new depth.
|
||||
*/
|
||||
protected function setNestedTransactionCount($v)
|
||||
{
|
||||
$this->nestedTransactionCount = $v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this PDO connection currently in-transaction?
|
||||
* This is equivalent to asking whether the current nested transaction count
|
||||
* is greater than 0.
|
||||
* @return boolean
|
||||
*/
|
||||
public function isInTransaction()
|
||||
{
|
||||
return ($this->getNestedTransactionCount() > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the connection contains a transaction that can be committed.
|
||||
* To be used in an evironment where Propelexceptions are caught.
|
||||
*
|
||||
* @return boolean True if the connection is in a committable transaction
|
||||
*/
|
||||
public function isCommitable()
|
||||
{
|
||||
return $this->isInTransaction() && !$this->isUncommitable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides PDO::beginTransaction() to prevent errors due to already-in-progress transaction.
|
||||
*/
|
||||
public function beginTransaction()
|
||||
{
|
||||
$return = true;
|
||||
if (!$this->nestedTransactionCount) {
|
||||
$return = parent::beginTransaction();
|
||||
if ($this->useDebug) {
|
||||
$this->log('Begin transaction', null, __METHOD__);
|
||||
}
|
||||
$this->isUncommitable = false;
|
||||
}
|
||||
$this->nestedTransactionCount++;
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides PDO::commit() to only commit the transaction if we are in the outermost
|
||||
* transaction nesting level.
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
$return = true;
|
||||
$opcount = $this->nestedTransactionCount;
|
||||
if ($opcount > 0) {
|
||||
if ($opcount === 1) {
|
||||
if ($this->isUncommitable) {
|
||||
throw new PropelException('Cannot commit because a nested transaction was rolled back');
|
||||
} else {
|
||||
$return = parent::commit();
|
||||
if ($this->useDebug) {
|
||||
$this->log('Commit transaction', null, __METHOD__);
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->nestedTransactionCount--;
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides PDO::rollBack() to only rollback the transaction if we are in the outermost
|
||||
* transaction nesting level
|
||||
* @return boolean Whether operation was successful.
|
||||
*/
|
||||
public function rollBack()
|
||||
{
|
||||
$return = true;
|
||||
$opcount = $this->nestedTransactionCount;
|
||||
if ($opcount > 0) {
|
||||
if ($opcount === 1) {
|
||||
$return = parent::rollBack();
|
||||
if ($this->useDebug) {
|
||||
$this->log('Rollback transaction', null, __METHOD__);
|
||||
}
|
||||
} else {
|
||||
$this->isUncommitable = true;
|
||||
}
|
||||
$this->nestedTransactionCount--;
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rollback the whole transaction, even if this is a nested rollback
|
||||
* and reset the nested transaction count to 0.
|
||||
* @return boolean Whether operation was successful.
|
||||
*/
|
||||
public function forceRollBack()
|
||||
{
|
||||
$return = true;
|
||||
if ($this->nestedTransactionCount) {
|
||||
// If we're in a transaction, always roll it back
|
||||
// regardless of nesting level.
|
||||
$return = parent::rollBack();
|
||||
|
||||
// reset nested transaction count to 0 so that we don't
|
||||
// try to commit (or rollback) the transaction outside this scope.
|
||||
$this->nestedTransactionCount = 0;
|
||||
|
||||
if ($this->useDebug) {
|
||||
$this->log('Rollback transaction', null, __METHOD__);
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a connection attribute.
|
||||
*
|
||||
* This is overridden here to provide support for setting Propel-specific attributes
|
||||
* too.
|
||||
*
|
||||
* @param int $attribute The attribute to set (e.g. PropelPDO::PROPEL_ATTR_CACHE_PREPARES).
|
||||
* @param mixed $value The attribute value.
|
||||
*/
|
||||
public function setAttribute($attribute, $value)
|
||||
{
|
||||
switch($attribute) {
|
||||
case self::PROPEL_ATTR_CACHE_PREPARES:
|
||||
$this->cachePreparedStatements = $value;
|
||||
break;
|
||||
default:
|
||||
parent::setAttribute($attribute, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a connection attribute.
|
||||
*
|
||||
* This is overridden here to provide support for setting Propel-specific attributes
|
||||
* too.
|
||||
*
|
||||
* @param int $attribute The attribute to get (e.g. PropelPDO::PROPEL_ATTR_CACHE_PREPARES).
|
||||
*/
|
||||
public function getAttribute($attribute)
|
||||
{
|
||||
switch($attribute) {
|
||||
case self::PROPEL_ATTR_CACHE_PREPARES:
|
||||
return $this->cachePreparedStatements;
|
||||
break;
|
||||
default:
|
||||
return parent::getAttribute($attribute);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a statement for execution and returns a statement object.
|
||||
*
|
||||
* Overrides PDO::prepare() in order to:
|
||||
* - Add logging and query counting if logging is true.
|
||||
* - Add query caching support if the PropelPDO::PROPEL_ATTR_CACHE_PREPARES was set to true.
|
||||
*
|
||||
* @param string $sql This must be a valid SQL statement for the target database server.
|
||||
* @param array One or more key => value pairs to set attribute values
|
||||
* for the PDOStatement object that this method returns.
|
||||
* @return PDOStatement
|
||||
*/
|
||||
public function prepare($sql, $driver_options = array())
|
||||
{
|
||||
if ($this->useDebug) {
|
||||
$debug = $this->getDebugSnapshot();
|
||||
}
|
||||
|
||||
if ($this->cachePreparedStatements) {
|
||||
if (!isset($this->preparedStatements[$sql])) {
|
||||
$return = parent::prepare($sql, $driver_options);
|
||||
$this->preparedStatements[$sql] = $return;
|
||||
} else {
|
||||
$return = $this->preparedStatements[$sql];
|
||||
}
|
||||
} else {
|
||||
$return = parent::prepare($sql, $driver_options);
|
||||
}
|
||||
|
||||
if ($this->useDebug) {
|
||||
$this->log($sql, null, __METHOD__, $debug);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute an SQL statement and return the number of affected rows.
|
||||
*
|
||||
* Overrides PDO::exec() to log queries when required
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function exec($sql)
|
||||
{
|
||||
if ($this->useDebug) {
|
||||
$debug = $this->getDebugSnapshot();
|
||||
}
|
||||
|
||||
$return = parent::exec($sql);
|
||||
|
||||
if ($this->useDebug) {
|
||||
$this->log($sql, null, __METHOD__, $debug);
|
||||
$this->setLastExecutedQuery($sql);
|
||||
$this->incrementQueryCount();
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes an SQL statement, returning a result set as a PDOStatement object.
|
||||
* Despite its signature here, this method takes a variety of parameters.
|
||||
*
|
||||
* Overrides PDO::query() to log queries when required
|
||||
*
|
||||
* @see http://php.net/manual/en/pdo.query.php for a description of the possible parameters.
|
||||
* @return PDOStatement
|
||||
*/
|
||||
public function query()
|
||||
{
|
||||
if ($this->useDebug) {
|
||||
$debug = $this->getDebugSnapshot();
|
||||
}
|
||||
|
||||
$args = func_get_args();
|
||||
if (version_compare(PHP_VERSION, '5.3', '<')) {
|
||||
$return = call_user_func_array(array($this, 'parent::query'), $args);
|
||||
} else {
|
||||
$return = call_user_func_array('parent::query', $args);
|
||||
}
|
||||
|
||||
if ($this->useDebug) {
|
||||
$sql = $args[0];
|
||||
$this->log($sql, null, __METHOD__, $debug);
|
||||
$this->setLastExecutedQuery($sql);
|
||||
$this->incrementQueryCount();
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears any stored prepared statements for this connection.
|
||||
*/
|
||||
public function clearStatementCache()
|
||||
{
|
||||
$this->preparedStatements = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the PDOStatement class for this connection.
|
||||
*
|
||||
* @param boolean $suppressError Whether to suppress an exception if the statement class cannot be set.
|
||||
* @throws PropelException if the statement class cannot be set (and $suppressError is false).
|
||||
*/
|
||||
protected function configureStatementClass($class = 'PDOStatement', $suppressError = true)
|
||||
{
|
||||
// extending PDOStatement is only supported with non-persistent connections
|
||||
if (!$this->getAttribute(PDO::ATTR_PERSISTENT)) {
|
||||
$this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array($class, array($this)));
|
||||
} elseif (!$suppressError) {
|
||||
throw new PropelException('Extending PDOStatement is not supported with persistent connections.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of queries this DebugPDO instance has performed on the database connection.
|
||||
*
|
||||
* When using DebugPDOStatement as the statement class, any queries by DebugPDOStatement instances
|
||||
* are counted as well.
|
||||
*
|
||||
* @return int
|
||||
* @throws PropelException if persistent connection is used (since unable to override PDOStatement in that case).
|
||||
*/
|
||||
public function getQueryCount()
|
||||
{
|
||||
// extending PDOStatement is not supported with persistent connections
|
||||
if ($this->getAttribute(PDO::ATTR_PERSISTENT)) {
|
||||
throw new PropelException('Extending PDOStatement is not supported with persistent connections. Count would be inaccurate, because we cannot count the PDOStatment::execute() calls. Either don\'t use persistent connections or don\'t call PropelPDO::getQueryCount()');
|
||||
}
|
||||
return $this->queryCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the number of queries performed by this DebugPDO instance.
|
||||
*
|
||||
* Returns the original number of queries (ie the value of $this->queryCount before calling this method).
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function incrementQueryCount()
|
||||
{
|
||||
$this->queryCount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SQL code for the latest query executed by Propel
|
||||
*
|
||||
* @return string Executable SQL code
|
||||
*/
|
||||
public function getLastExecutedQuery()
|
||||
{
|
||||
return $this->lastExecutedQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the SQL code for the latest query executed by Propel
|
||||
*
|
||||
* @param string $query Executable SQL code
|
||||
*/
|
||||
public function setLastExecutedQuery($query)
|
||||
{
|
||||
$this->lastExecutedQuery = $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or disable the query debug features
|
||||
*
|
||||
* @var boolean $value True to enable debug (default), false to disable it
|
||||
*/
|
||||
public function useDebug($value = true)
|
||||
{
|
||||
if ($value) {
|
||||
$this->configureStatementClass('DebugPDOStatement', $suppress = true);
|
||||
} else {
|
||||
// reset query logging
|
||||
$this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('PDOStatement'));
|
||||
$this->setLastExecutedQuery('');
|
||||
$this->queryCount = 0;
|
||||
}
|
||||
$this->clearStatementCache();
|
||||
$this->useDebug = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the logging level to use for logging method calls and SQL statements.
|
||||
*
|
||||
* @param int $level Value of one of the Propel::LOG_* class constants.
|
||||
*/
|
||||
public function setLogLevel($level)
|
||||
{
|
||||
$this->logLevel = $level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a logger to use.
|
||||
*
|
||||
* The logger will be used by this class to log various method calls and their properties.
|
||||
*
|
||||
* @param BasicLogger $logger A Logger with an API compatible with BasicLogger (or PEAR Log).
|
||||
*/
|
||||
public function setLogger($logger)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the logger in use.
|
||||
*
|
||||
* @return BasicLogger $logger A Logger with an API compatible with BasicLogger (or PEAR Log).
|
||||
*/
|
||||
public function getLogger()
|
||||
{
|
||||
return $this->logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the method call or SQL using the Propel::log() method or a registered logger class.
|
||||
*
|
||||
* @uses self::getLogPrefix()
|
||||
* @see self::setLogger()
|
||||
*
|
||||
* @param string $msg Message to log.
|
||||
* @param int $level (optional) Log level to use; will use self::setLogLevel() specified level by default.
|
||||
* @param string $methodName (optional) Name of the method whose execution is being logged.
|
||||
* @param array $debugSnapshot (optional) Previous return value from self::getDebugSnapshot().
|
||||
*/
|
||||
public function log($msg, $level = null, $methodName = null, array $debugSnapshot = null)
|
||||
{
|
||||
// If logging has been specifically disabled, this method won't do anything
|
||||
if (!$this->getLoggingConfig('enabled', true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the method being logged isn't one of the ones to be logged, bail
|
||||
if (!in_array($methodName, $this->getLoggingConfig('methods', self::$defaultLogMethods))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If a logging level wasn't provided, use the default one
|
||||
if ($level === null) {
|
||||
$level = $this->logLevel;
|
||||
}
|
||||
|
||||
// Determine if this query is slow enough to warrant logging
|
||||
if ($this->getLoggingConfig("onlyslow", self::DEFAULT_ONLYSLOW_ENABLED)) {
|
||||
$now = $this->getDebugSnapshot();
|
||||
if ($now['microtime'] - $debugSnapshot['microtime'] < $this->getLoggingConfig("details.slow.threshold", self::DEFAULT_SLOW_THRESHOLD)) return;
|
||||
}
|
||||
|
||||
// If the necessary additional parameters were given, get the debug log prefix for the log line
|
||||
if ($methodName && $debugSnapshot) {
|
||||
$msg = $this->getLogPrefix($methodName, $debugSnapshot) . $msg;
|
||||
}
|
||||
|
||||
// We won't log empty messages
|
||||
if (!$msg) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Delegate the actual logging forward
|
||||
if ($this->logger) {
|
||||
$this->logger->log($msg, $level);
|
||||
} else {
|
||||
Propel::log($msg, $level);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a snapshot of the current values of some functions useful in debugging.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDebugSnapshot()
|
||||
{
|
||||
if ($this->useDebug) {
|
||||
return array(
|
||||
'microtime' => microtime(true),
|
||||
'memory_get_usage' => memory_get_usage($this->getLoggingConfig('realmemoryusage', false)),
|
||||
'memory_get_peak_usage' => memory_get_peak_usage($this->getLoggingConfig('realmemoryusage', false)),
|
||||
);
|
||||
} else {
|
||||
throw new PropelException('Should not get debug snapshot when not debugging');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a named configuration item from the Propel runtime configuration, from under the
|
||||
* 'debugpdo.logging' prefix. If such a configuration setting hasn't been set, the given default
|
||||
* value will be returned.
|
||||
*
|
||||
* @param string $key Key for which to return the value.
|
||||
* @param mixed $defaultValue Default value to apply if config item hasn't been set.
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getLoggingConfig($key, $defaultValue)
|
||||
{
|
||||
return Propel::getConfiguration(PropelConfiguration::TYPE_OBJECT)->getParameter("debugpdo.logging.$key", $defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a prefix that may be prepended to a log line, containing debug information according
|
||||
* to the current configuration.
|
||||
*
|
||||
* Uses a given $debugSnapshot to calculate how much time has passed since the call to self::getDebugSnapshot(),
|
||||
* how much the memory consumption by PHP has changed etc.
|
||||
*
|
||||
* @see self::getDebugSnapshot()
|
||||
*
|
||||
* @param string $methodName Name of the method whose execution is being logged.
|
||||
* @param array $debugSnapshot A previous return value from self::getDebugSnapshot().
|
||||
* @return string
|
||||
*/
|
||||
protected function getLogPrefix($methodName, $debugSnapshot)
|
||||
{
|
||||
$prefix = '';
|
||||
$now = $this->getDebugSnapshot();
|
||||
$logDetails = array_keys($this->getLoggingConfig('details', array()));
|
||||
$innerGlue = $this->getLoggingConfig('innerglue', ': ');
|
||||
$outerGlue = $this->getLoggingConfig('outerglue', ' | ');
|
||||
|
||||
// Iterate through each detail that has been configured to be enabled
|
||||
foreach ($logDetails as $detailName) {
|
||||
|
||||
if (!$this->getLoggingConfig("details.$detailName.enabled", false))
|
||||
continue;
|
||||
|
||||
switch ($detailName) {
|
||||
|
||||
case 'slow';
|
||||
$value = $now['microtime'] - $debugSnapshot['microtime'] >= $this->getLoggingConfig("details.$detailName.threshold", self::DEFAULT_SLOW_THRESHOLD) ? 'YES' : ' NO';
|
||||
break;
|
||||
|
||||
case 'time':
|
||||
$value = number_format($now['microtime'] - $debugSnapshot['microtime'], $this->getLoggingConfig("details.$detailName.precision", 3)) . ' sec';
|
||||
$value = str_pad($value, $this->getLoggingConfig("details.$detailName.pad", 10), ' ', STR_PAD_LEFT);
|
||||
break;
|
||||
|
||||
case 'mem':
|
||||
$value = self::getReadableBytes($now['memory_get_usage'], $this->getLoggingConfig("details.$detailName.precision", 1));
|
||||
$value = str_pad($value, $this->getLoggingConfig("details.$detailName.pad", 9), ' ', STR_PAD_LEFT);
|
||||
break;
|
||||
|
||||
case 'memdelta':
|
||||
$value = $now['memory_get_usage'] - $debugSnapshot['memory_get_usage'];
|
||||
$value = ($value > 0 ? '+' : '') . self::getReadableBytes($value, $this->getLoggingConfig("details.$detailName.precision", 1));
|
||||
$value = str_pad($value, $this->getLoggingConfig("details.$detailName.pad", 10), ' ', STR_PAD_LEFT);
|
||||
break;
|
||||
|
||||
case 'mempeak':
|
||||
$value = self::getReadableBytes($now['memory_get_peak_usage'], $this->getLoggingConfig("details.$detailName.precision", 1));
|
||||
$value = str_pad($value, $this->getLoggingConfig("details.$detailName.pad", 9), ' ', STR_PAD_LEFT);
|
||||
break;
|
||||
|
||||
case 'querycount':
|
||||
$value = $this->getQueryCount();
|
||||
$value = str_pad($value, $this->getLoggingConfig("details.$detailName.pad", 2), ' ', STR_PAD_LEFT);
|
||||
break;
|
||||
|
||||
case 'method':
|
||||
$value = $methodName;
|
||||
$value = str_pad($value, $this->getLoggingConfig("details.$detailName.pad", 28), ' ', STR_PAD_RIGHT);
|
||||
break;
|
||||
|
||||
default:
|
||||
$value = 'n/a';
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
$prefix .= $detailName . $innerGlue . $value . $outerGlue;
|
||||
|
||||
}
|
||||
|
||||
return $prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human-readable representation of the given byte count.
|
||||
*
|
||||
* @param int $bytes Byte count to convert.
|
||||
* @param int $precision How many decimals to include.
|
||||
* @return string
|
||||
*/
|
||||
protected function getReadableBytes($bytes, $precision)
|
||||
{
|
||||
$suffix = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
|
||||
$total = count($suffix);
|
||||
|
||||
for ($i = 0; $bytes > 1024 && $i < $total; $i++)
|
||||
$bytes /= 1024;
|
||||
|
||||
return number_format($bytes, $precision) . ' ' . $suffix[$i];
|
||||
}
|
||||
|
||||
/**
|
||||
* If so configured, makes an entry to the log of the state of this object just prior to its destruction.
|
||||
* Add PropelPDO::__destruct to $defaultLogMethods to see this message
|
||||
*
|
||||
* @see self::log()
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
if ($this->useDebug) {
|
||||
$this->log('Closing connection', null, __METHOD__, $this->getDebugSnapshot());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
50
library/propel/runtime/lib/exception/PropelException.php
Normal file
50
library/propel/runtime/lib/exception/PropelException.php
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* The base class of all exceptions thrown by Propel.
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.exception
|
||||
*/
|
||||
class PropelException extends Exception {
|
||||
|
||||
/** The nested "cause" exception. */
|
||||
protected $cause;
|
||||
|
||||
function __construct($p1, $p2 = null) {
|
||||
|
||||
$cause = null;
|
||||
|
||||
if ($p2 !== null) {
|
||||
$msg = $p1;
|
||||
$cause = $p2;
|
||||
} else {
|
||||
if ($p1 instanceof Exception) {
|
||||
$msg = "";
|
||||
$cause = $p1;
|
||||
} else {
|
||||
$msg = $p1;
|
||||
}
|
||||
}
|
||||
|
||||
parent::__construct($msg);
|
||||
|
||||
if ($cause !== null) {
|
||||
$this->cause = $cause;
|
||||
$this->message .= " [wrapped: " . $cause->getMessage() ."]";
|
||||
}
|
||||
}
|
||||
|
||||
function getCause() {
|
||||
return $this->cause;
|
||||
}
|
||||
|
||||
}
|
144
library/propel/runtime/lib/formatter/ModelWith.php
Executable file
144
library/propel/runtime/lib/formatter/ModelWith.php
Executable file
|
@ -0,0 +1,144 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Data object to describe a joined hydration in a Model Query
|
||||
* ModelWith objects are used by formatters to hydrate related objects
|
||||
*
|
||||
* @author Francois Zaninotto (Propel)
|
||||
* @package propel.runtime.query
|
||||
*/
|
||||
class ModelWith
|
||||
{
|
||||
protected $modelName = '';
|
||||
protected $modelPeerName = '';
|
||||
protected $isSingleTableInheritance = false;
|
||||
protected $isAdd = false;
|
||||
protected $relationName = '';
|
||||
protected $relationMethod = '';
|
||||
protected $relatedClass;
|
||||
|
||||
public function __construct(ModelJoin $join = null)
|
||||
{
|
||||
if (null !== $join) {
|
||||
$this->init($join);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the joined hydration schema based on a join object.
|
||||
* Fills the ModelWith properties using a ModelJoin as source
|
||||
*
|
||||
* @param ModelJoin $join
|
||||
*/
|
||||
public function init(ModelJoin $join)
|
||||
{
|
||||
$tableMap = $join->getTableMap();
|
||||
$this->modelName = $tableMap->getClassname();
|
||||
$this->modelPeerName = $tableMap->getPeerClassname();
|
||||
$this->isSingleTableInheritance = $tableMap->isSingleTableInheritance();
|
||||
$relation = $join->getRelationMap();
|
||||
if ($relation->getType() == RelationMap::ONE_TO_MANY) {
|
||||
$this->isAdd = true;
|
||||
$this->relationName = $relation->getName() . 's';
|
||||
$this->relationMethod = 'add' . $relation->getName();
|
||||
} else {
|
||||
$this->relationName = $relation->getName();
|
||||
$this->relationMethod = 'set' . $relation->getName();
|
||||
}
|
||||
if (!$join->isPrimary()) {
|
||||
$this->relatedClass = $join->hasLeftTableAlias() ? $join->getLeftTableAlias() : $relation->getLeftTable()->getPhpName();
|
||||
}
|
||||
}
|
||||
|
||||
// DataObject getters & setters
|
||||
|
||||
public function setModelName($modelName)
|
||||
{
|
||||
$this->modelName = $modelName;
|
||||
}
|
||||
|
||||
public function getModelName()
|
||||
{
|
||||
return $this->modelName;
|
||||
}
|
||||
|
||||
public function setModelPeerName($modelPeerName)
|
||||
{
|
||||
$this->modelPeerName = $modelPeerName;
|
||||
}
|
||||
|
||||
public function getModelPeerName()
|
||||
{
|
||||
return $this->modelPeerName;
|
||||
}
|
||||
|
||||
public function setIsSingleTableInheritance($isSingleTableInheritance)
|
||||
{
|
||||
$this->isSingleTableInheritance = $isSingleTableInheritance;
|
||||
}
|
||||
|
||||
public function isSingleTableInheritance()
|
||||
{
|
||||
return $this->isSingleTableInheritance;
|
||||
}
|
||||
|
||||
public function setIsAdd($isAdd)
|
||||
{
|
||||
$this->isAdd = $isAdd;;
|
||||
}
|
||||
|
||||
public function isAdd()
|
||||
{
|
||||
return $this->isAdd;
|
||||
}
|
||||
|
||||
public function setRelationName($relationName)
|
||||
{
|
||||
$this->relationName = $relationName;
|
||||
}
|
||||
|
||||
public function getRelationName()
|
||||
{
|
||||
return $this->relationName;
|
||||
}
|
||||
|
||||
public function setRelationMethod($relationMethod)
|
||||
{
|
||||
$this->relationMethod = $relationMethod;
|
||||
}
|
||||
|
||||
public function getRelationMethod()
|
||||
{
|
||||
return $this->relationMethod;
|
||||
}
|
||||
|
||||
public function setRelatedClass($relatedClass)
|
||||
{
|
||||
$this->relatedClass = $relatedClass;
|
||||
}
|
||||
|
||||
public function getRelatedClass()
|
||||
{
|
||||
return $this->relatedClass;
|
||||
}
|
||||
|
||||
// Utility methods
|
||||
|
||||
public function isPrimary()
|
||||
{
|
||||
return null === $this->relatedClass;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return sprintf("modelName: %s, relationName: %s, relationMethod: %s, relatedClass: %s", $this->modelName, $this->relationName, $this->relationMethod, $this->relatedClass);
|
||||
}
|
||||
}
|
170
library/propel/runtime/lib/formatter/PropelArrayFormatter.php
Normal file
170
library/propel/runtime/lib/formatter/PropelArrayFormatter.php
Normal file
|
@ -0,0 +1,170 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Array formatter for Propel query
|
||||
* format() returns a PropelArrayCollection of associative arrays
|
||||
*
|
||||
* @author Francois Zaninotto
|
||||
* @version $Revision: 1796 $
|
||||
* @package propel.runtime.formatter
|
||||
*/
|
||||
class PropelArrayFormatter extends PropelFormatter
|
||||
{
|
||||
protected $collectionName = 'PropelArrayCollection';
|
||||
protected $alreadyHydratedObjects = array();
|
||||
protected $emptyVariable;
|
||||
|
||||
public function format(PDOStatement $stmt)
|
||||
{
|
||||
$this->checkInit();
|
||||
if($class = $this->collectionName) {
|
||||
$collection = new $class();
|
||||
$collection->setModel($this->class);
|
||||
$collection->setFormatter($this);
|
||||
} else {
|
||||
$collection = array();
|
||||
}
|
||||
if ($this->isWithOneToMany() && $this->hasLimit) {
|
||||
throw new PropelException('Cannot use limit() in conjunction with with() on a one-to-many relationship. Please remove the with() call, or the limit() call.');
|
||||
}
|
||||
while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
|
||||
if ($object = &$this->getStructuredArrayFromRow($row)) {
|
||||
$collection[] = $object;
|
||||
}
|
||||
}
|
||||
$this->currentObjects = array();
|
||||
$this->alreadyHydratedObjects = array();
|
||||
$stmt->closeCursor();
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
public function formatOne(PDOStatement $stmt)
|
||||
{
|
||||
$this->checkInit();
|
||||
$result = null;
|
||||
while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
|
||||
if ($object = &$this->getStructuredArrayFromRow($row)) {
|
||||
$result = &$object;
|
||||
}
|
||||
}
|
||||
$this->currentObjects = array();
|
||||
$this->alreadyHydratedObjects = array();
|
||||
$stmt->closeCursor();
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats an ActiveRecord object
|
||||
*
|
||||
* @param BaseObject $record the object to format
|
||||
*
|
||||
* @return array The original record turned into an array
|
||||
*/
|
||||
public function formatRecord($record = null)
|
||||
{
|
||||
return $record ? $record->toArray() : array();
|
||||
}
|
||||
|
||||
public function isObjectFormatter()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Hydrates a series of objects from a result row
|
||||
* The first object to hydrate is the model of the Criteria
|
||||
* The following objects (the ones added by way of ModelCriteria::with()) are linked to the first one
|
||||
*
|
||||
* @param array $row associative array indexed by column number,
|
||||
* as returned by PDOStatement::fetch(PDO::FETCH_NUM)
|
||||
*
|
||||
* @return Array
|
||||
*/
|
||||
public function &getStructuredArrayFromRow($row)
|
||||
{
|
||||
$col = 0;
|
||||
|
||||
// hydrate main object or take it from registry
|
||||
$mainObjectIsNew = false;
|
||||
$mainKey = call_user_func(array($this->peer, 'getPrimaryKeyHashFromRow'), $row);
|
||||
// we hydrate the main object even in case of a one-to-many relationship
|
||||
// in order to get the $col variable increased anyway
|
||||
$obj = $this->getSingleObjectFromRow($row, $this->class, $col);
|
||||
if (!isset($this->alreadyHydratedObjects[$this->class][$mainKey])) {
|
||||
$this->alreadyHydratedObjects[$this->class][$mainKey] = $obj->toArray();
|
||||
$mainObjectIsNew = true;
|
||||
}
|
||||
|
||||
$hydrationChain = array();
|
||||
|
||||
// related objects added using with()
|
||||
foreach ($this->getWith() as $relAlias => $modelWith) {
|
||||
|
||||
// determine class to use
|
||||
if ($modelWith->isSingleTableInheritance()) {
|
||||
$class = call_user_func(array($modelWith->getModelPeerName(), 'getOMClass'), $row, $col, false);
|
||||
$refl = new ReflectionClass($class);
|
||||
if ($refl->isAbstract()) {
|
||||
$col += constant($class . 'Peer::NUM_COLUMNS');
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
$class = $modelWith->getModelName();
|
||||
}
|
||||
|
||||
// hydrate related object or take it from registry
|
||||
$key = call_user_func(array($modelWith->getModelPeerName(), 'getPrimaryKeyHashFromRow'), $row, $col);
|
||||
// we hydrate the main object even in case of a one-to-many relationship
|
||||
// in order to get the $col variable increased anyway
|
||||
$secondaryObject = $this->getSingleObjectFromRow($row, $class, $col);
|
||||
if (!isset($this->alreadyHydratedObjects[$relAlias][$key])) {
|
||||
|
||||
if ($secondaryObject->isPrimaryKeyNull()) {
|
||||
$this->alreadyHydratedObjects[$relAlias][$key] = array();
|
||||
} else {
|
||||
$this->alreadyHydratedObjects[$relAlias][$key] = $secondaryObject->toArray();
|
||||
}
|
||||
}
|
||||
|
||||
if ($modelWith->isPrimary()) {
|
||||
$arrayToAugment = &$this->alreadyHydratedObjects[$this->class][$mainKey];
|
||||
} else {
|
||||
$arrayToAugment = &$hydrationChain[$modelWith->getRelatedClass()];
|
||||
}
|
||||
|
||||
if ($modelWith->isAdd()) {
|
||||
if (!isset($arrayToAugment[$modelWith->getRelationName()]) || !in_array($this->alreadyHydratedObjects[$relAlias][$key], $arrayToAugment[$modelWith->getRelationName()])) {
|
||||
$arrayToAugment[$modelWith->getRelationName()][] = &$this->alreadyHydratedObjects[$relAlias][$key];
|
||||
}
|
||||
} else {
|
||||
$arrayToAugment[$modelWith->getRelationName()] = &$this->alreadyHydratedObjects[$relAlias][$key];
|
||||
}
|
||||
|
||||
$hydrationChain[$relAlias] = &$this->alreadyHydratedObjects[$relAlias][$key];
|
||||
}
|
||||
|
||||
// columns added using withColumn()
|
||||
foreach ($this->getAsColumns() as $alias => $clause) {
|
||||
$this->alreadyHydratedObjects[$this->class][$mainKey][$alias] = $row[$col];
|
||||
$col++;
|
||||
}
|
||||
|
||||
if ($mainObjectIsNew) {
|
||||
return $this->alreadyHydratedObjects[$this->class][$mainKey];
|
||||
} else {
|
||||
// we still need to return a reference to something to avoid a warning
|
||||
return $emptyVariable;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
202
library/propel/runtime/lib/formatter/PropelFormatter.php
Normal file
202
library/propel/runtime/lib/formatter/PropelFormatter.php
Normal file
|
@ -0,0 +1,202 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstract class for query formatter
|
||||
*
|
||||
* @author Francois Zaninotto
|
||||
* @version $Revision: 1796 $
|
||||
* @package propel.runtime.formatter
|
||||
*/
|
||||
abstract class PropelFormatter
|
||||
{
|
||||
protected
|
||||
$dbName,
|
||||
$class,
|
||||
$peer,
|
||||
$with = array(),
|
||||
$asColumns = array(),
|
||||
$hasLimit = false,
|
||||
$currentObjects = array();
|
||||
|
||||
public function __construct(ModelCriteria $criteria = null)
|
||||
{
|
||||
if (null !== $criteria) {
|
||||
$this->init($criteria);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the hydration schema based on a query object.
|
||||
* Fills the Formatter's properties using a Criteria as source
|
||||
*
|
||||
* @param ModelCriteria $criteria
|
||||
*
|
||||
* @return PropelFormatter The current formatter object
|
||||
*/
|
||||
public function init(ModelCriteria $criteria)
|
||||
{
|
||||
$this->dbName = $criteria->getDbName();
|
||||
$this->class = $criteria->getModelName();
|
||||
$this->peer = $criteria->getModelPeerName();
|
||||
$this->setWith($criteria->getWith());
|
||||
$this->asColumns = $criteria->getAsColumns();
|
||||
$this->hasLimit = $criteria->getLimit() != 0;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
// DataObject getters & setters
|
||||
|
||||
public function setDbName($dbName)
|
||||
{
|
||||
$this->dbName = $dbName;
|
||||
}
|
||||
|
||||
public function getDbName()
|
||||
{
|
||||
return $this->dbName;
|
||||
}
|
||||
|
||||
public function setClass($class)
|
||||
{
|
||||
$this->class = $class;
|
||||
}
|
||||
|
||||
public function getClass()
|
||||
{
|
||||
return $this->class;
|
||||
}
|
||||
|
||||
public function setPeer($peer)
|
||||
{
|
||||
$this->peer = $peer;
|
||||
}
|
||||
|
||||
public function getPeer()
|
||||
{
|
||||
return $this->peer;
|
||||
}
|
||||
|
||||
public function setWith($withs = array())
|
||||
{
|
||||
$this->with = array();
|
||||
foreach ($withs as $relation => $join) {
|
||||
$this->with[$relation] = new ModelWith($join);
|
||||
}
|
||||
}
|
||||
|
||||
public function getWith()
|
||||
{
|
||||
return $this->with;
|
||||
}
|
||||
|
||||
public function setAsColumns($asColumns = array())
|
||||
{
|
||||
$this->asColumns = $asColumns;
|
||||
}
|
||||
|
||||
public function getAsColumns()
|
||||
{
|
||||
return $this->asColumns;
|
||||
}
|
||||
|
||||
public function setHasLimit($hasLimit = false)
|
||||
{
|
||||
$this->hasLimit = $hasLimit;
|
||||
}
|
||||
|
||||
public function hasLimit()
|
||||
{
|
||||
return $this->hasLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats an ActiveRecord object
|
||||
*
|
||||
* @param BaseObject $record the object to format
|
||||
*
|
||||
* @return BaseObject The original record
|
||||
*/
|
||||
public function formatRecord($record = null)
|
||||
{
|
||||
return $record;
|
||||
}
|
||||
|
||||
abstract public function format(PDOStatement $stmt);
|
||||
|
||||
abstract public function formatOne(PDOStatement $stmt);
|
||||
|
||||
abstract public function isObjectFormatter();
|
||||
|
||||
public function checkInit()
|
||||
{
|
||||
if (null === $this->peer) {
|
||||
throw new PropelException('You must initialize a formatter object before calling format() or formatOne()');
|
||||
}
|
||||
}
|
||||
|
||||
public function getTableMap()
|
||||
{
|
||||
return Propel::getDatabaseMap($this->dbName)->getTableByPhpName($this->class);
|
||||
}
|
||||
|
||||
protected function isWithOneToMany()
|
||||
{
|
||||
foreach ($this->with as $modelWith) {
|
||||
if ($modelWith->isAdd()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the worker object for the class.
|
||||
* To save memory, we don't create a new object for each row,
|
||||
* But we keep hydrating a single object per class.
|
||||
* The column offset in the row is used to index the array of classes
|
||||
* As there may be more than one object of the same class in the chain
|
||||
*
|
||||
* @param int $col Offset of the object in the list of objects to hydrate
|
||||
* @param string $class Propel model object class
|
||||
*
|
||||
* @return BaseObject
|
||||
*/
|
||||
protected function getWorkerObject($col, $class)
|
||||
{
|
||||
if(isset($this->currentObjects[$col])) {
|
||||
$this->currentObjects[$col]->clear();
|
||||
} else {
|
||||
$this->currentObjects[$col] = new $class();
|
||||
}
|
||||
return $this->currentObjects[$col];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a Propel object hydrated from a selection of columns in statement row
|
||||
*
|
||||
* @param array $row associative array indexed by column number,
|
||||
* as returned by PDOStatement::fetch(PDO::FETCH_NUM)
|
||||
* @param string $class The classname of the object to create
|
||||
* @param int $col The start column for the hydration (modified)
|
||||
*
|
||||
* @return BaseObject
|
||||
*/
|
||||
public function getSingleObjectFromRow($row, $class, &$col = 0)
|
||||
{
|
||||
$obj = $this->getWorkerObject($col, $class);
|
||||
$col = $obj->hydrate($row, $col);
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
|
||||
}
|
112
library/propel/runtime/lib/formatter/PropelObjectFormatter.php
Normal file
112
library/propel/runtime/lib/formatter/PropelObjectFormatter.php
Normal file
|
@ -0,0 +1,112 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Object formatter for Propel query
|
||||
* format() returns a PropelObjectCollection of Propel model objects
|
||||
*
|
||||
* @author Francois Zaninotto
|
||||
* @version $Revision: 1733 $
|
||||
* @package propel.runtime.formatter
|
||||
*/
|
||||
class PropelObjectFormatter extends PropelFormatter
|
||||
{
|
||||
protected $collectionName = 'PropelObjectCollection';
|
||||
|
||||
public function format(PDOStatement $stmt)
|
||||
{
|
||||
$this->checkInit();
|
||||
if($class = $this->collectionName) {
|
||||
$collection = new $class();
|
||||
$collection->setModel($this->class);
|
||||
$collection->setFormatter($this);
|
||||
} else {
|
||||
$collection = array();
|
||||
}
|
||||
if ($this->isWithOneToMany()) {
|
||||
if ($this->hasLimit) {
|
||||
throw new PropelException('Cannot use limit() in conjunction with with() on a one-to-many relationship. Please remove the with() call, or the limit() call.');
|
||||
}
|
||||
$pks = array();
|
||||
while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
|
||||
$object = $this->getAllObjectsFromRow($row);
|
||||
$pk = $object->getPrimaryKey();
|
||||
if (!in_array($pk, $pks)) {
|
||||
$collection[] = $object;
|
||||
$pks[] = $pk;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// only many-to-one relationships
|
||||
while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
|
||||
$collection[] = $this->getAllObjectsFromRow($row);
|
||||
}
|
||||
}
|
||||
$stmt->closeCursor();
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
public function formatOne(PDOStatement $stmt)
|
||||
{
|
||||
$this->checkInit();
|
||||
$result = null;
|
||||
while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
|
||||
$result = $this->getAllObjectsFromRow($row);
|
||||
}
|
||||
$stmt->closeCursor();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function isObjectFormatter()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hydrates a series of objects from a result row
|
||||
* The first object to hydrate is the model of the Criteria
|
||||
* The following objects (the ones added by way of ModelCriteria::with()) are linked to the first one
|
||||
*
|
||||
* @param array $row associative array indexed by column number,
|
||||
* as returned by PDOStatement::fetch(PDO::FETCH_NUM)
|
||||
*
|
||||
* @return BaseObject
|
||||
*/
|
||||
public function getAllObjectsFromRow($row)
|
||||
{
|
||||
// main object
|
||||
list($obj, $col) = call_user_func(array($this->peer, 'populateObject'), $row);
|
||||
// related objects added using with()
|
||||
foreach ($this->getWith() as $class => $modelWith) {
|
||||
list($endObject, $col) = call_user_func(array($modelWith->getModelPeerName(), 'populateObject'), $row, $col);
|
||||
// as we may be in a left join, the endObject may be empty
|
||||
// in which case it should not be related to the previous object
|
||||
if (null === $endObject || $endObject->isPrimaryKeyNull()) {
|
||||
continue;
|
||||
}
|
||||
if (isset($hydrationChain)) {
|
||||
$hydrationChain[$class] = $endObject;
|
||||
} else {
|
||||
$hydrationChain = array($class => $endObject);
|
||||
}
|
||||
$startObject = $modelWith->isPrimary() ? $obj : $hydrationChain[$modelWith->getRelatedClass()];
|
||||
call_user_func(array($startObject, $modelWith->getRelationMethod()), $endObject);
|
||||
}
|
||||
// columns added using withColumn()
|
||||
foreach ($this->getAsColumns() as $alias => $clause) {
|
||||
$obj->setVirtualColumn($alias, $row[$col]);
|
||||
$col++;
|
||||
}
|
||||
return $obj;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Object formatter for Propel query
|
||||
* format() returns a PropelOnDemandCollection that hydrates objects as the use iterates on the collection
|
||||
* This formatter consumes less memory than the PropelObjectFormatter, but doesn't use Instance Pool
|
||||
*
|
||||
* @author Francois Zaninotto
|
||||
* @version $Revision: 1733 $
|
||||
* @package propel.runtime.formatter
|
||||
*/
|
||||
class PropelOnDemandFormatter extends PropelObjectFormatter
|
||||
{
|
||||
protected $collectionName = 'PropelOnDemandCollection';
|
||||
protected $isSingleTableInheritance = false;
|
||||
|
||||
public function init(ModelCriteria $criteria)
|
||||
{
|
||||
parent::init($criteria);
|
||||
$this->isSingleTableInheritance = $criteria->getTableMap()->isSingleTableInheritance();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function format(PDOStatement $stmt)
|
||||
{
|
||||
$this->checkInit();
|
||||
if ($this->isWithOneToMany()) {
|
||||
throw new PropelException('PropelOnDemandFormatter cannot hydrate related objects using a one-to-many relationship. Try removing with() from your query.');
|
||||
}
|
||||
$class = $this->collectionName;
|
||||
$collection = new $class();
|
||||
$collection->setModel($this->class);
|
||||
$collection->initIterator($this, $stmt);
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hydrates a series of objects from a result row
|
||||
* The first object to hydrate is the model of the Criteria
|
||||
* The following objects (the ones added by way of ModelCriteria::with()) are linked to the first one
|
||||
*
|
||||
* @param array $row associative array indexed by column number,
|
||||
* as returned by PDOStatement::fetch(PDO::FETCH_NUM)
|
||||
*
|
||||
* @return BaseObject
|
||||
*/
|
||||
public function getAllObjectsFromRow($row)
|
||||
{
|
||||
$col = 0;
|
||||
// main object
|
||||
$class = $this->isSingleTableInheritance ? call_user_func(array($his->peer, 'getOMClass'), $row, $col, false) : $this->class;
|
||||
$obj = $this->getSingleObjectFromRow($row, $class, $col);
|
||||
// related objects using 'with'
|
||||
foreach ($this->getWith() as $modelWith) {
|
||||
if ($modelWith->isSingleTableInheritance()) {
|
||||
$class = call_user_func(array($modelWith->getModelPeerName(), 'getOMClass'), $row, $col, false);
|
||||
$refl = new ReflectionClass($class);
|
||||
if ($refl->isAbstract()) {
|
||||
$col += constant($class . 'Peer::NUM_COLUMNS');
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
$class = $modelWith->getModelName();
|
||||
}
|
||||
$endObject = $this->getSingleObjectFromRow($row, $class, $col);
|
||||
// as we may be in a left join, the endObject may be empty
|
||||
// in which case it should not be related to the previous object
|
||||
if (null === $endObject || $endObject->isPrimaryKeyNull()) {
|
||||
continue;
|
||||
}
|
||||
if (isset($hydrationChain)) {
|
||||
$hydrationChain[$class] = $endObject;
|
||||
} else {
|
||||
$hydrationChain = array($class => $endObject);
|
||||
}
|
||||
$startObject = $modelWith->isPrimary() ? $obj : $hydrationChain[$modelWith->getRelatedClass()];
|
||||
call_user_func(array($startObject, $modelWith->getRelationMethod()), $endObject);
|
||||
}
|
||||
foreach ($this->getAsColumns() as $alias => $clause) {
|
||||
$obj->setVirtualColumn($alias, $row[$col]);
|
||||
$col++;
|
||||
}
|
||||
return $obj;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* statement formatter for Propel query
|
||||
* format() returns a PDO statement
|
||||
*
|
||||
* @author Francois Zaninotto
|
||||
* @version $Revision: 1796 $
|
||||
* @package propel.runtime.formatter
|
||||
*/
|
||||
class PropelStatementFormatter extends PropelFormatter
|
||||
{
|
||||
public function format(PDOStatement $stmt)
|
||||
{
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
public function formatOne(PDOStatement $stmt)
|
||||
{
|
||||
if ($stmt->rowCount() == 0) {
|
||||
return null;
|
||||
} else {
|
||||
return $stmt;
|
||||
}
|
||||
}
|
||||
|
||||
public function formatRecord($record = null)
|
||||
{
|
||||
throw new PropelException('The Statement formatter cannot transform a record into a statement');
|
||||
}
|
||||
|
||||
public function isObjectFormatter()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
91
library/propel/runtime/lib/logger/BasicLogger.php
Normal file
91
library/propel/runtime/lib/logger/BasicLogger.php
Normal file
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is a minimalistic interface that any logging class must implement for Propel.
|
||||
*
|
||||
* The API for this interface is based on the PEAR::Log interface. It provides a simple
|
||||
* API that can be used by Propel independently of Log backend.
|
||||
*
|
||||
* PEAR::Log and perhaps the Log API was developed by Chuck Hagenbuch <chuck@horde.org>
|
||||
* and Jon Parise <jon@php.net>.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.logger
|
||||
*/
|
||||
interface BasicLogger
|
||||
{
|
||||
|
||||
/**
|
||||
* A convenience function for logging an alert event.
|
||||
*
|
||||
* @param mixed $message String or Exception object containing the message
|
||||
* to log.
|
||||
*/
|
||||
public function alert($message);
|
||||
|
||||
/**
|
||||
* A convenience function for logging a critical event.
|
||||
*
|
||||
* @param mixed $message String or Exception object containing the message
|
||||
* to log.
|
||||
*/
|
||||
public function crit($message);
|
||||
|
||||
/**
|
||||
* A convenience function for logging an error event.
|
||||
*
|
||||
* @param mixed $message String or Exception object containing the message
|
||||
* to log.
|
||||
*/
|
||||
public function err($message);
|
||||
|
||||
/**
|
||||
* A convenience function for logging a warning event.
|
||||
*
|
||||
* @param mixed $message String or Exception object containing the message
|
||||
* to log.
|
||||
*/
|
||||
public function warning($message);
|
||||
/**
|
||||
* A convenience function for logging an critical event.
|
||||
*
|
||||
* @param mixed $message String or Exception object containing the message
|
||||
* to log.
|
||||
*/
|
||||
public function notice($message);
|
||||
/**
|
||||
* A convenience function for logging an critical event.
|
||||
*
|
||||
* @param mixed $message String or Exception object containing the message
|
||||
* to log.
|
||||
*/
|
||||
public function info($message);
|
||||
|
||||
/**
|
||||
* A convenience function for logging a debug event.
|
||||
*
|
||||
* @param mixed $message String or Exception object containing the message
|
||||
* to log.
|
||||
*/
|
||||
public function debug($message);
|
||||
|
||||
/**
|
||||
* Primary method to handle logging.
|
||||
*
|
||||
* @param mixed $message String or Exception object containing the message
|
||||
* to log.
|
||||
* @param int $severity The numeric severity. Defaults to null so that no
|
||||
* assumptions are made about the logging backend.
|
||||
*/
|
||||
public function log($message, $severity = null);
|
||||
|
||||
}
|
160
library/propel/runtime/lib/logger/MojaviLogAdapter.php
Normal file
160
library/propel/runtime/lib/logger/MojaviLogAdapter.php
Normal file
|
@ -0,0 +1,160 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Mojavi logging adapter for propel
|
||||
*
|
||||
* @author Brandon Keepers <brandon@opensoul.org>
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.logger
|
||||
*/
|
||||
class MojaviLogAdapter implements BasicLogger
|
||||
{
|
||||
|
||||
/**
|
||||
* Instance of mojavi logger
|
||||
*/
|
||||
private $logger = null;
|
||||
|
||||
/**
|
||||
* constructor for setting up Mojavi log adapter
|
||||
*
|
||||
* @param ErrorLog $logger instance of Mojavi error log obtained by
|
||||
* calling LogManager::getLogger();
|
||||
*/
|
||||
public function __construct($logger = null)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience function for logging an alert event.
|
||||
*
|
||||
* @param mixed $message String or Exception object containing the message
|
||||
* to log.
|
||||
*/
|
||||
public function alert($message)
|
||||
{
|
||||
$this->log($message, 'alert');
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience function for logging a critical event.
|
||||
*
|
||||
* @param mixed $message String or Exception object containing the message
|
||||
* to log.
|
||||
*/
|
||||
public function crit($message)
|
||||
{
|
||||
$this->log($message, 'crit');
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience function for logging an error event.
|
||||
*
|
||||
* @param mixed $message String or Exception object containing the message
|
||||
* to log.
|
||||
*/
|
||||
public function err($message)
|
||||
{
|
||||
$this->log($message, 'err');
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience function for logging a warning event.
|
||||
*
|
||||
* @param mixed $message String or Exception object containing the message
|
||||
* to log.
|
||||
*/
|
||||
public function warning($message)
|
||||
{
|
||||
$this->log($message, 'warning');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A convenience function for logging an critical event.
|
||||
*
|
||||
* @param mixed $message String or Exception object containing the message
|
||||
* to log.
|
||||
*/
|
||||
public function notice($message)
|
||||
{
|
||||
$this->log($message, 'notice');
|
||||
}
|
||||
/**
|
||||
* A convenience function for logging an critical event.
|
||||
*
|
||||
* @param mixed $message String or Exception object containing the message
|
||||
* to log.
|
||||
*/
|
||||
public function info($message)
|
||||
{
|
||||
$this->log($message, 'info');
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience function for logging a debug event.
|
||||
*
|
||||
* @param mixed $message String or Exception object containing the message
|
||||
* to log.
|
||||
*/
|
||||
public function debug($message)
|
||||
{
|
||||
$this->log($message, 'debug');
|
||||
}
|
||||
|
||||
/**
|
||||
* Primary method to handle logging.
|
||||
*
|
||||
* @param mixed $message String or Exception object containing the message
|
||||
* to log.
|
||||
* @param int $severity The numeric severity. Defaults to null so that no
|
||||
* assumptions are made about the logging backend.
|
||||
*/
|
||||
public function log($message, $severity = null)
|
||||
{
|
||||
if (is_null($this->logger))
|
||||
$this->logger = LogManager::getLogger('propel');
|
||||
|
||||
switch($severity)
|
||||
{
|
||||
case 'crit':
|
||||
$method = 'fatal';
|
||||
break;
|
||||
case 'err':
|
||||
$method = 'error';
|
||||
break;
|
||||
case 'alert':
|
||||
case 'warning':
|
||||
$method = 'warning';
|
||||
break;
|
||||
case 'notice':
|
||||
case 'info':
|
||||
$method = 'info';
|
||||
break;
|
||||
case 'debug':
|
||||
default:
|
||||
$method = 'debug';
|
||||
}
|
||||
|
||||
// get a backtrace to pass class, function, file, & line to Mojavi logger
|
||||
$trace = debug_backtrace();
|
||||
|
||||
// call the appropriate Mojavi logger method
|
||||
$this->logger->{$method} (
|
||||
$message,
|
||||
$trace[2]['class'],
|
||||
$trace[2]['function'],
|
||||
$trace[1]['file'],
|
||||
$trace[1]['line']
|
||||
);
|
||||
}
|
||||
}
|
464
library/propel/runtime/lib/map/ColumnMap.php
Normal file
464
library/propel/runtime/lib/map/ColumnMap.php
Normal file
|
@ -0,0 +1,464 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* ColumnMap is used to model a column of a table in a database.
|
||||
*
|
||||
* GENERAL NOTE
|
||||
* ------------
|
||||
* The propel.map classes are abstract building-block classes for modeling
|
||||
* the database at runtime. These classes are similar (a lite version) to the
|
||||
* propel.engine.database.model classes, which are build-time modeling classes.
|
||||
* These classes in themselves do not do any database metadata lookups.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org> (Propel)
|
||||
* @author John D. McNally <jmcnally@collab.net> (Torque)
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.map
|
||||
*/
|
||||
class ColumnMap
|
||||
{
|
||||
|
||||
// Propel type of the column
|
||||
protected $type;
|
||||
|
||||
// Size of the column
|
||||
protected $size = 0;
|
||||
|
||||
// Is it a primary key?
|
||||
protected $pk = false;
|
||||
|
||||
// Is null value allowed?
|
||||
protected $notNull = false;
|
||||
|
||||
// The default value for this column
|
||||
protected $defaultValue;
|
||||
|
||||
// Name of the table that this column is related to
|
||||
protected $relatedTableName = "";
|
||||
|
||||
// Name of the column that this column is related to
|
||||
protected $relatedColumnName = "";
|
||||
|
||||
// The TableMap for this column
|
||||
protected $table;
|
||||
|
||||
// The name of the column
|
||||
protected $columnName;
|
||||
|
||||
// The php name of the column
|
||||
protected $phpName;
|
||||
|
||||
// The validators for this column
|
||||
protected $validators = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $name The name of the column.
|
||||
* @param TableMap containingTable TableMap of the table this column is in.
|
||||
*/
|
||||
public function __construct($name, TableMap $containingTable)
|
||||
{
|
||||
$this->columnName = $name;
|
||||
$this->table = $containingTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of a column.
|
||||
*
|
||||
* @return string A String with the column name.
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->columnName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the table map this column belongs to.
|
||||
* @return TableMap
|
||||
*/
|
||||
public function getTable()
|
||||
{
|
||||
return $this->table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the table this column is in.
|
||||
*
|
||||
* @return string A String with the table name.
|
||||
*/
|
||||
public function getTableName()
|
||||
{
|
||||
return $this->table->getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the table name + column name.
|
||||
*
|
||||
* @return string A String with the full column name.
|
||||
*/
|
||||
public function getFullyQualifiedName()
|
||||
{
|
||||
return $this->getTableName() . "." . $this->columnName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the php anme of this column.
|
||||
*
|
||||
* @param string $phpName A string representing the PHP name.
|
||||
* @return void
|
||||
*/
|
||||
public function setPhpName($phpName)
|
||||
{
|
||||
$this->phpName = $phpName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of a column.
|
||||
*
|
||||
* @return string A String with the column name.
|
||||
*/
|
||||
public function getPhpName()
|
||||
{
|
||||
return $this->phpName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Propel type of this column.
|
||||
*
|
||||
* @param string $type A string representing the Propel type (e.g. PropelColumnTypes::DATE).
|
||||
* @return void
|
||||
*/
|
||||
public function setType($type)
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Propel type of this column.
|
||||
*
|
||||
* @return string A string representing the Propel type (e.g. PropelColumnTypes::DATE).
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the PDO type of this column.
|
||||
*
|
||||
* @return int The PDO::PARMA_* value
|
||||
*/
|
||||
public function getPdoType()
|
||||
{
|
||||
return PropelColumnTypes::getPdoType($this->type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this is a BLOB, LONGVARBINARY, or VARBINARY.
|
||||
* @return boolean
|
||||
*/
|
||||
public function isLob()
|
||||
{
|
||||
return ($this->type == PropelColumnTypes::BLOB || $this->type == PropelColumnTypes::VARBINARY || $this->type == PropelColumnTypes::LONGVARBINARY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this is a DATE/TIME/TIMESTAMP column.
|
||||
*
|
||||
* @return boolean
|
||||
* @since 1.3
|
||||
*/
|
||||
public function isTemporal()
|
||||
{
|
||||
return ($this->type == PropelColumnTypes::TIMESTAMP || $this->type == PropelColumnTypes::DATE || $this->type == PropelColumnTypes::TIME || $this->type == PropelColumnTypes::BU_DATE || $this->type == PropelColumnTypes::BU_TIMESTAMP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this is a DATE/TIME/TIMESTAMP column that is post-epoch (1970).
|
||||
*
|
||||
* PHP cannot handle pre-epoch timestamps well -- hence the need to differentiate
|
||||
* between epoch and pre-epoch timestamps.
|
||||
*
|
||||
* @return boolean
|
||||
* @deprecated Propel supports non-epoch dates
|
||||
*/
|
||||
public function isEpochTemporal()
|
||||
{
|
||||
return ($this->type == PropelColumnTypes::TIMESTAMP || $this->type == PropelColumnTypes::DATE || $this->type == PropelColumnTypes::TIME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this column is numeric (int, decimal, bigint etc).
|
||||
* @return boolean
|
||||
*/
|
||||
public function isNumeric()
|
||||
{
|
||||
return ($this->type == PropelColumnTypes::NUMERIC || $this->type == PropelColumnTypes::DECIMAL || $this->type == PropelColumnTypes::TINYINT || $this->type == PropelColumnTypes::SMALLINT || $this->type == PropelColumnTypes::INTEGER || $this->type == PropelColumnTypes::BIGINT || $this->type == PropelColumnTypes::REAL || $this->type == PropelColumnTypes::FLOAT || $this->type == PropelColumnTypes::DOUBLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this column is a text column (varchar, char, longvarchar).
|
||||
* @return boolean
|
||||
*/
|
||||
public function isText()
|
||||
{
|
||||
return ($this->type == PropelColumnTypes::VARCHAR || $this->type == PropelColumnTypes::LONGVARCHAR || $this->type == PropelColumnTypes::CHAR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the size of this column.
|
||||
*
|
||||
* @param int $size An int specifying the size.
|
||||
* @return void
|
||||
*/
|
||||
public function setSize($size)
|
||||
{
|
||||
$this->size = $size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size of this column.
|
||||
*
|
||||
* @return int An int specifying the size.
|
||||
*/
|
||||
public function getSize()
|
||||
{
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if this column is a primary key or not.
|
||||
*
|
||||
* @param boolean $pk True if column is a primary key.
|
||||
* @return void
|
||||
*/
|
||||
public function setPrimaryKey($pk)
|
||||
{
|
||||
$this->pk = $pk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this column a primary key?
|
||||
*
|
||||
* @return boolean True if column is a primary key.
|
||||
*/
|
||||
public function isPrimaryKey()
|
||||
{
|
||||
return $this->pk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if this column may be null.
|
||||
*
|
||||
* @param boolean nn True if column may be null.
|
||||
* @return void
|
||||
*/
|
||||
public function setNotNull($nn)
|
||||
{
|
||||
$this->notNull = $nn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is null value allowed ?
|
||||
*
|
||||
* @return boolean True if column may not be null.
|
||||
*/
|
||||
public function isNotNull()
|
||||
{
|
||||
return ($this->notNull || $this->isPrimaryKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default value for this column.
|
||||
* @param mixed $defaultValue the default value for the column
|
||||
* @return void
|
||||
*/
|
||||
public function setDefaultValue($defaultValue)
|
||||
{
|
||||
$this->defaultValue = $defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default value for this column.
|
||||
* @return mixed String or NULL
|
||||
*/
|
||||
public function getDefaultValue()
|
||||
{
|
||||
return $this->defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the foreign key for this column.
|
||||
*
|
||||
* @param string tableName The name of the table that is foreign.
|
||||
* @param string columnName The name of the column that is foreign.
|
||||
* @return void
|
||||
*/
|
||||
public function setForeignKey($tableName, $columnName)
|
||||
{
|
||||
if ($tableName && $columnName) {
|
||||
$this->relatedTableName = $tableName;
|
||||
$this->relatedColumnName = $columnName;
|
||||
} else {
|
||||
$this->relatedTableName = "";
|
||||
$this->relatedColumnName = "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this column a foreign key?
|
||||
*
|
||||
* @return boolean True if column is a foreign key.
|
||||
*/
|
||||
public function isForeignKey()
|
||||
{
|
||||
if ($this->relatedTableName) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the RelationMap object for this foreign key
|
||||
*/
|
||||
public function getRelation()
|
||||
{
|
||||
if(!$this->relatedTableName) return null;
|
||||
foreach ($this->getTable()->getRelations() as $name => $relation)
|
||||
{
|
||||
if($relation->getType() == RelationMap::MANY_TO_ONE)
|
||||
{
|
||||
if ($relation->getForeignTable()->getName() == $this->getRelatedTableName()
|
||||
&& array_key_exists($this->getFullyQualifiedName(), $relation->getColumnMappings()))
|
||||
{
|
||||
return $relation;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the table.column that this column is related to.
|
||||
*
|
||||
* @return string A String with the full name for the related column.
|
||||
*/
|
||||
public function getRelatedName()
|
||||
{
|
||||
return $this->relatedTableName . "." . $this->relatedColumnName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the table name that this column is related to.
|
||||
*
|
||||
* @return string A String with the name for the related table.
|
||||
*/
|
||||
public function getRelatedTableName()
|
||||
{
|
||||
return $this->relatedTableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the column name that this column is related to.
|
||||
*
|
||||
* @return string A String with the name for the related column.
|
||||
*/
|
||||
public function getRelatedColumnName()
|
||||
{
|
||||
return $this->relatedColumnName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the TableMap object that this column is related to.
|
||||
*
|
||||
* @return TableMap The related TableMap object
|
||||
* @throws PropelException when called on a column with no foreign key
|
||||
*/
|
||||
public function getRelatedTable()
|
||||
{
|
||||
if ($this->relatedTableName) {
|
||||
return $this->table->getDatabaseMap()->getTable($this->relatedTableName);
|
||||
} else {
|
||||
throw new PropelException("Cannot fetch RelatedTable for column with no foreign key: " . $this->columnName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the TableMap object that this column is related to.
|
||||
*
|
||||
* @return ColumnMap The related ColumnMap object
|
||||
* @throws PropelException when called on a column with no foreign key
|
||||
*/
|
||||
public function getRelatedColumn()
|
||||
{
|
||||
return $this->getRelatedTable()->getColumn($this->relatedColumnName);
|
||||
}
|
||||
|
||||
public function addValidator($validator)
|
||||
{
|
||||
$this->validators[] = $validator;
|
||||
}
|
||||
|
||||
public function hasValidators()
|
||||
{
|
||||
return count($this->validators) > 0;
|
||||
}
|
||||
|
||||
public function getValidators()
|
||||
{
|
||||
return $this->validators;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs DB-specific ignore case, but only if the column type necessitates it.
|
||||
* @param string $str The expression we want to apply the ignore case formatting to (e.g. the column name).
|
||||
* @param DBAdapter $db
|
||||
*/
|
||||
public function ignoreCase($str, DBAdapter $db)
|
||||
{
|
||||
if ($this->isText()) {
|
||||
return $db->ignoreCase($str);
|
||||
} else {
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the column name, removing table prefix and uppercasing.
|
||||
*
|
||||
* article.first_name becomes FIRST_NAME
|
||||
*
|
||||
* @param string $name
|
||||
* @return string Normalized column name.
|
||||
*/
|
||||
public static function normalizeName($name)
|
||||
{
|
||||
if (false !== ($pos = strpos($name, '.'))) {
|
||||
$name = substr($name, $pos + 1);
|
||||
}
|
||||
$name = strtoupper($name);
|
||||
return $name;
|
||||
}
|
||||
|
||||
// deprecated methods
|
||||
|
||||
/**
|
||||
* Gets column name
|
||||
* @deprecated Use getName() instead
|
||||
* @return string
|
||||
* @deprecated Use getName() instead.
|
||||
*/
|
||||
public function getColumnName()
|
||||
{
|
||||
return $this->getName();
|
||||
}
|
||||
}
|
191
library/propel/runtime/lib/map/DatabaseMap.php
Normal file
191
library/propel/runtime/lib/map/DatabaseMap.php
Normal file
|
@ -0,0 +1,191 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* DatabaseMap is used to model a database.
|
||||
*
|
||||
* GENERAL NOTE
|
||||
* ------------
|
||||
* The propel.map classes are abstract building-block classes for modeling
|
||||
* the database at runtime. These classes are similar (a lite version) to the
|
||||
* propel.engine.database.model classes, which are build-time modeling classes.
|
||||
* These classes in themselves do not do any database metadata lookups.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org> (Propel)
|
||||
* @author John D. McNally <jmcnally@collab.net> (Torque)
|
||||
* @author Daniel Rall <dlr@collab.net> (Torque)
|
||||
* @version $Revision: 1802 $
|
||||
* @package propel.runtime.map
|
||||
*/
|
||||
class DatabaseMap
|
||||
{
|
||||
|
||||
/** @var string Name of the database. */
|
||||
protected $name;
|
||||
|
||||
/** @var array TableMap[] Tables in the database, using table name as key */
|
||||
protected $tables = array();
|
||||
|
||||
/** @var array TableMap[] Tables in the database, using table phpName as key */
|
||||
protected $tablesByPhpName = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $name Name of the database.
|
||||
*/
|
||||
public function __construct($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of this database.
|
||||
*
|
||||
* @return string The name of the database.
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new table to the database by name.
|
||||
*
|
||||
* @param string $tableName The name of the table.
|
||||
* @return TableMap The newly created TableMap.
|
||||
*/
|
||||
public function addTable($tableName)
|
||||
{
|
||||
$this->tables[$tableName] = new TableMap($tableName, $this);
|
||||
return $this->tables[$tableName];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new table object to the database.
|
||||
*
|
||||
* @param TableMap $table The table to add
|
||||
*/
|
||||
public function addTableObject(TableMap $table)
|
||||
{
|
||||
$table->setDatabaseMap($this);
|
||||
$this->tables[$table->getName()] = $table;
|
||||
$this->tablesByPhpName[$table->getClassname()] = $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new table to the database, using the tablemap class name.
|
||||
*
|
||||
* @param string $tableMapClass The name of the table map to add
|
||||
* @return TableMap The TableMap object
|
||||
*/
|
||||
public function addTableFromMapClass($tableMapClass)
|
||||
{
|
||||
$table = new $tableMapClass();
|
||||
if(!$this->hasTable($table->getName())) {
|
||||
$this->addTableObject($table);
|
||||
return $table;
|
||||
} else {
|
||||
return $this->getTable($table->getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this database contain this specific table?
|
||||
*
|
||||
* @param string $name The String representation of the table.
|
||||
* @return boolean True if the database contains the table.
|
||||
*/
|
||||
public function hasTable($name)
|
||||
{
|
||||
if ( strpos($name, '.') > 0) {
|
||||
$name = substr($name, 0, strpos($name, '.'));
|
||||
}
|
||||
return array_key_exists($name, $this->tables);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a TableMap for the table by name.
|
||||
*
|
||||
* @param string $name Name of the table.
|
||||
* @return TableMap A TableMap
|
||||
* @throws PropelException if the table is undefined
|
||||
*/
|
||||
public function getTable($name)
|
||||
{
|
||||
if (!isset($this->tables[$name])) {
|
||||
throw new PropelException("Cannot fetch TableMap for undefined table: " . $name );
|
||||
}
|
||||
return $this->tables[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a TableMap[] of all of the tables in the database.
|
||||
*
|
||||
* @return array A TableMap[].
|
||||
*/
|
||||
public function getTables()
|
||||
{
|
||||
return $this->tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a ColumnMap for the column by name.
|
||||
* Name must be fully qualified, e.g. book.AUTHOR_ID
|
||||
*
|
||||
* @param $qualifiedColumnName Name of the column.
|
||||
* @return ColumnMap A TableMap
|
||||
* @throws PropelException if the table is undefined, or if the table is undefined
|
||||
*/
|
||||
public function getColumn($qualifiedColumnName)
|
||||
{
|
||||
list($tableName, $columnName) = explode('.', $qualifiedColumnName);
|
||||
return $this->getTable($tableName)->getColumn($columnName, false);
|
||||
}
|
||||
|
||||
// deprecated methods
|
||||
|
||||
/**
|
||||
* Does this database contain this specific table?
|
||||
*
|
||||
* @deprecated Use hasTable() instead
|
||||
* @param string $name The String representation of the table.
|
||||
* @return boolean True if the database contains the table.
|
||||
*/
|
||||
public function containsTable($name)
|
||||
{
|
||||
return $this->hasTable($name);
|
||||
}
|
||||
|
||||
public function getTableByPhpName($phpName)
|
||||
{
|
||||
if (array_key_exists($phpName, $this->tablesByPhpName)) {
|
||||
return $this->tablesByPhpName[$phpName];
|
||||
} else if (class_exists($tmClass = $phpName . 'TableMap')) {
|
||||
$this->addTableFromMapClass($tmClass);
|
||||
return $this->tablesByPhpName[$phpName];
|
||||
} else if (class_exists($tmClass = substr_replace($phpName, '\\map\\', strrpos($phpName, '\\'), 1) . 'TableMap')) {
|
||||
$this->addTableFromMapClass($tmClass);
|
||||
return $this->tablesByPhpName[$phpName];
|
||||
} else {
|
||||
throw new PropelException("Cannot fetch TableMap for undefined table phpName: " . $phpName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to get the DBAdapter registered with Propel for this database.
|
||||
* @return DBAdapter
|
||||
* @see Propel::getDB(string)
|
||||
*/
|
||||
public function getDBAdapter()
|
||||
{
|
||||
return Propel::getDB($this->name);
|
||||
}
|
||||
}
|
299
library/propel/runtime/lib/map/RelationMap.php
Normal file
299
library/propel/runtime/lib/map/RelationMap.php
Normal file
|
@ -0,0 +1,299 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* RelationMap is used to model a database relationship.
|
||||
*
|
||||
* GENERAL NOTE
|
||||
* ------------
|
||||
* The propel.map classes are abstract building-block classes for modeling
|
||||
* the database at runtime. These classes are similar (a lite version) to the
|
||||
* propel.engine.database.model classes, which are build-time modeling classes.
|
||||
* These classes in themselves do not do any database metadata lookups.
|
||||
*
|
||||
* @author Francois Zaninotto
|
||||
* @version $Revision: 1728 $
|
||||
* @package propel.runtime.map
|
||||
*/
|
||||
class RelationMap
|
||||
{
|
||||
|
||||
const
|
||||
// types
|
||||
MANY_TO_ONE = 1,
|
||||
ONE_TO_MANY = 2,
|
||||
ONE_TO_ONE = 3,
|
||||
MANY_TO_MANY = 4,
|
||||
// representations
|
||||
LOCAL_TO_FOREIGN = 0,
|
||||
LEFT_TO_RIGHT = 1;
|
||||
|
||||
protected
|
||||
$name,
|
||||
$type,
|
||||
$localTable,
|
||||
$foreignTable,
|
||||
$localColumns = array(),
|
||||
$foreignColumns = array(),
|
||||
$onUpdate, $onDelete;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $name Name of the relation.
|
||||
*/
|
||||
public function __construct($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of this relation.
|
||||
*
|
||||
* @return string The name of the relation.
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the type
|
||||
*
|
||||
* @param integer $type The relation type (either self::MANY_TO_ONE, self::ONE_TO_MANY, or self::ONE_TO_ONE)
|
||||
*/
|
||||
public function setType($type)
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type
|
||||
*
|
||||
* @return integer the relation type
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the local table
|
||||
*
|
||||
* @param TableMap $table The local table for this relationship
|
||||
*/
|
||||
public function setLocalTable($table)
|
||||
{
|
||||
$this->localTable = $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the local table
|
||||
*
|
||||
* @return TableMap The local table for this relationship
|
||||
*/
|
||||
public function getLocalTable()
|
||||
{
|
||||
return $this->localTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the foreign table
|
||||
*
|
||||
* @param TableMap $table The foreign table for this relationship
|
||||
*/
|
||||
public function setForeignTable($table)
|
||||
{
|
||||
$this->foreignTable = $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the foreign table
|
||||
*
|
||||
* @return TableMap The foreign table for this relationship
|
||||
*/
|
||||
public function getForeignTable()
|
||||
{
|
||||
return $this->foreignTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the left table of the relation
|
||||
*
|
||||
* @return TableMap The left table for this relationship
|
||||
*/
|
||||
public function getLeftTable()
|
||||
{
|
||||
return ($this->getType() == RelationMap::MANY_TO_ONE) ? $this->getLocalTable() : $this->getForeignTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the right table of the relation
|
||||
*
|
||||
* @return TableMap The right table for this relationship
|
||||
*/
|
||||
public function getRightTable()
|
||||
{
|
||||
return ($this->getType() == RelationMap::MANY_TO_ONE) ? $this->getForeignTable() : $this->getLocalTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a column mapping
|
||||
*
|
||||
* @param ColumnMap $local The local column
|
||||
* @param ColumnMap $foreign The foreign column
|
||||
*/
|
||||
public function addColumnMapping(ColumnMap $local, ColumnMap $foreign)
|
||||
{
|
||||
$this->localColumns[] = $local;
|
||||
$this->foreignColumns[] = $foreign;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an associative array mapping local column names to foreign column names
|
||||
* The arrangement of the returned array depends on the $direction parameter:
|
||||
* - If the value is RelationMap::LOCAL_TO_FOREIGN, then the returned array is local => foreign
|
||||
* - If the value is RelationMap::LEFT_TO_RIGHT, then the returned array is left => right
|
||||
*
|
||||
* @param int $direction How the associative array must return columns
|
||||
* @return Array Associative array (local => foreign) of fully qualified column names
|
||||
*/
|
||||
public function getColumnMappings($direction = RelationMap::LOCAL_TO_FOREIGN)
|
||||
{
|
||||
$h = array();
|
||||
if ($direction == RelationMap::LEFT_TO_RIGHT && $this->getType() == RelationMap::MANY_TO_ONE) {
|
||||
$direction = RelationMap::LOCAL_TO_FOREIGN;
|
||||
}
|
||||
for ($i=0, $size=count($this->localColumns); $i < $size; $i++) {
|
||||
if ($direction == RelationMap::LOCAL_TO_FOREIGN) {
|
||||
$h[$this->localColumns[$i]->getFullyQualifiedName()] = $this->foreignColumns[$i]->getFullyQualifiedName();
|
||||
} else {
|
||||
$h[$this->foreignColumns[$i]->getFullyQualifiedName()] = $this->localColumns[$i]->getFullyQualifiedName();
|
||||
}
|
||||
}
|
||||
return $h;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the relation has more than one column mapping
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isComposite()
|
||||
{
|
||||
return $this->countColumnMappings() > 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of column mappings
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function countColumnMappings()
|
||||
{
|
||||
return count($this->localColumns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the local columns
|
||||
*
|
||||
* @return Array list of ColumnMap objects
|
||||
*/
|
||||
public function getLocalColumns()
|
||||
{
|
||||
return $this->localColumns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the foreign columns
|
||||
*
|
||||
* @return Array list of ColumnMap objects
|
||||
*/
|
||||
public function getForeignColumns()
|
||||
{
|
||||
return $this->foreignColumns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the left columns of the relation
|
||||
*
|
||||
* @return array of ColumnMap objects
|
||||
*/
|
||||
public function getLeftColumns()
|
||||
{
|
||||
return ($this->getType() == RelationMap::MANY_TO_ONE) ? $this->getLocalColumns() : $this->getForeignColumns();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the right columns of the relation
|
||||
*
|
||||
* @return array of ColumnMap objects
|
||||
*/
|
||||
public function getRightColumns()
|
||||
{
|
||||
return ($this->getType() == RelationMap::MANY_TO_ONE) ? $this->getForeignColumns() : $this->getLocalColumns();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the onUpdate behavior
|
||||
*
|
||||
* @param string $onUpdate
|
||||
*/
|
||||
public function setOnUpdate($onUpdate)
|
||||
{
|
||||
$this->onUpdate = $onUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the onUpdate behavior
|
||||
*
|
||||
* @return integer the relation type
|
||||
*/
|
||||
public function getOnUpdate()
|
||||
{
|
||||
return $this->onUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the onDelete behavior
|
||||
*
|
||||
* @param string $onDelete
|
||||
*/
|
||||
public function setOnDelete($onDelete)
|
||||
{
|
||||
$this->onDelete = $onDelete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the onDelete behavior
|
||||
*
|
||||
* @return integer the relation type
|
||||
*/
|
||||
public function getOnDelete()
|
||||
{
|
||||
return $this->onDelete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the symmetrical relation
|
||||
*
|
||||
* @return RelationMap
|
||||
*/
|
||||
public function getSymmetricalRelation()
|
||||
{
|
||||
$localMapping = array($this->getLeftColumns(), $this->getRightColumns());
|
||||
foreach ($this->getRightTable()->getRelations() as $relation) {
|
||||
if ($localMapping == array($relation->getRightColumns(), $relation->getLeftColumns())) {
|
||||
return $relation;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
712
library/propel/runtime/lib/map/TableMap.php
Normal file
712
library/propel/runtime/lib/map/TableMap.php
Normal file
|
@ -0,0 +1,712 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* TableMap is used to model a table in a database.
|
||||
*
|
||||
* GENERAL NOTE
|
||||
* ------------
|
||||
* The propel.map classes are abstract building-block classes for modeling
|
||||
* the database at runtime. These classes are similar (a lite version) to the
|
||||
* propel.engine.database.model classes, which are build-time modeling classes.
|
||||
* These classes in themselves do not do any database metadata lookups.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org> (Propel)
|
||||
* @author John D. McNally <jmcnally@collab.net> (Torque)
|
||||
* @author Daniel Rall <dlr@finemaltcoding.com> (Torque)
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.map
|
||||
*/
|
||||
class TableMap
|
||||
{
|
||||
|
||||
/**
|
||||
* Columns in the table
|
||||
* @var array TableMap[]
|
||||
*/
|
||||
protected $columns = array();
|
||||
|
||||
/**
|
||||
* Columns in the table, using table phpName as key
|
||||
* @var array TableMap[]
|
||||
*/
|
||||
protected $columnsByPhpName = array();
|
||||
|
||||
// The database this table belongs to
|
||||
protected $dbMap;
|
||||
|
||||
// The name of the table
|
||||
protected $tableName;
|
||||
|
||||
// The PHP name of the table
|
||||
protected $phpName;
|
||||
|
||||
// The Classname for this table
|
||||
protected $classname;
|
||||
|
||||
// The Package for this table
|
||||
protected $package;
|
||||
|
||||
// Whether to use an id generator for pkey
|
||||
protected $useIdGenerator;
|
||||
|
||||
// Whether the table uses single table inheritance
|
||||
protected $isSingleTableInheritance = false;
|
||||
|
||||
// The primary key columns in the table
|
||||
protected $primaryKeys = array();
|
||||
|
||||
// The foreign key columns in the table
|
||||
protected $foreignKeys = array();
|
||||
|
||||
// The relationships in the table
|
||||
protected $relations = array();
|
||||
|
||||
// Relations are lazy loaded. This property tells if the relations are loaded or not
|
||||
protected $relationsBuilt = false;
|
||||
|
||||
// Object to store information that is needed if the for generating primary keys
|
||||
protected $pkInfo;
|
||||
|
||||
/**
|
||||
* Construct a new TableMap.
|
||||
*
|
||||
*/
|
||||
public function __construct($name = null, $dbMap = null)
|
||||
{
|
||||
if (null !== $name) {
|
||||
$this->setName($name);
|
||||
}
|
||||
if (null !== $dbMap) {
|
||||
$this->setDatabaseMap($dbMap);
|
||||
}
|
||||
$this->initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the TableMap to build columns, relations, etc
|
||||
* This method should be overridden by descendents
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the DatabaseMap containing this TableMap.
|
||||
*
|
||||
* @param DatabaseMap $dbMap A DatabaseMap.
|
||||
*/
|
||||
public function setDatabaseMap(DatabaseMap $dbMap)
|
||||
{
|
||||
$this->dbMap = $dbMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the DatabaseMap containing this TableMap.
|
||||
*
|
||||
* @return DatabaseMap A DatabaseMap.
|
||||
*/
|
||||
public function getDatabaseMap()
|
||||
{
|
||||
return $this->dbMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the Table.
|
||||
*
|
||||
* @param string $name The name of the table.
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$this->tableName = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the Table.
|
||||
*
|
||||
* @return string A String with the name of the table.
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the PHP name of the Table.
|
||||
*
|
||||
* @param string $phpName The PHP Name for this table
|
||||
*/
|
||||
public function setPhpName($phpName)
|
||||
{
|
||||
$this->phpName = $phpName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the PHP name of the Table.
|
||||
*
|
||||
* @return string A String with the name of the table.
|
||||
*/
|
||||
public function getPhpName()
|
||||
{
|
||||
return $this->phpName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Classname of the Table. Could be useful for calling
|
||||
* Peer and Object methods dynamically.
|
||||
* @param string $classname The Classname
|
||||
*/
|
||||
public function setClassname($classname)
|
||||
{
|
||||
$this->classname = $classname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Classname of the Propel Class belonging to this table.
|
||||
* @return string
|
||||
*/
|
||||
public function getClassname()
|
||||
{
|
||||
return $this->classname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Peer Classname of the Propel Class belonging to this table.
|
||||
* @return string
|
||||
*/
|
||||
public function getPeerClassname()
|
||||
{
|
||||
return constant($this->classname . '::PEER');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Package of the Table
|
||||
*
|
||||
* @param string $package The Package
|
||||
*/
|
||||
public function setPackage($package)
|
||||
{
|
||||
$this->package = $package;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Package of the table.
|
||||
* @return string
|
||||
*/
|
||||
public function getPackage()
|
||||
{
|
||||
return $this->package;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether or not to use Id generator for primary key.
|
||||
* @param boolean $bit
|
||||
*/
|
||||
public function setUseIdGenerator($bit)
|
||||
{
|
||||
$this->useIdGenerator = $bit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to use Id generator for primary key.
|
||||
* @return boolean
|
||||
*/
|
||||
public function isUseIdGenerator()
|
||||
{
|
||||
return $this->useIdGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether or not to this table uses single table inheritance
|
||||
* @param boolean $bit
|
||||
*/
|
||||
public function setSingleTableInheritance($bit)
|
||||
{
|
||||
$this->isSingleTableInheritance = $bit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this table uses single table inheritance
|
||||
* @return boolean
|
||||
*/
|
||||
public function isSingleTableInheritance()
|
||||
{
|
||||
return $this->isSingleTableInheritance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the pk information needed to generate a key
|
||||
*
|
||||
* @param $pkInfo information needed to generate a key
|
||||
*/
|
||||
public function setPrimaryKeyMethodInfo($pkInfo)
|
||||
{
|
||||
$this->pkInfo = $pkInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the information used to generate a primary key
|
||||
*
|
||||
* @return An Object.
|
||||
*/
|
||||
public function getPrimaryKeyMethodInfo()
|
||||
{
|
||||
return $this->pkInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a column to the table.
|
||||
*
|
||||
* @param string name A String with the column name.
|
||||
* @param string $type A string specifying the Propel type.
|
||||
* @param boolean $isNotNull Whether column does not allow NULL values.
|
||||
* @param int $size An int specifying the size.
|
||||
* @param boolean $pk True if column is a primary key.
|
||||
* @param string $fkTable A String with the foreign key table name.
|
||||
* @param $fkColumn A String with the foreign key column name.
|
||||
* @param string $defaultValue The default value for this column.
|
||||
* @return ColumnMap The newly created column.
|
||||
*/
|
||||
public function addColumn($name, $phpName, $type, $isNotNull = false, $size = null, $defaultValue = null, $pk = false, $fkTable = null, $fkColumn = null)
|
||||
{
|
||||
$col = new ColumnMap($name, $this);
|
||||
$col->setType($type);
|
||||
$col->setSize($size);
|
||||
$col->setPhpName($phpName);
|
||||
$col->setNotNull($isNotNull);
|
||||
$col->setDefaultValue($defaultValue);
|
||||
|
||||
if ($pk) {
|
||||
$col->setPrimaryKey(true);
|
||||
$this->primaryKeys[$name] = $col;
|
||||
}
|
||||
|
||||
if ($fkTable && $fkColumn) {
|
||||
$col->setForeignKey($fkTable, $fkColumn);
|
||||
$this->foreignKeys[$name] = $col;
|
||||
}
|
||||
|
||||
$this->columns[$name] = $col;
|
||||
$this->columnsByPhpName[$phpName] = $col;
|
||||
|
||||
return $col;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a pre-created column to this table. It will replace any
|
||||
* existing column.
|
||||
*
|
||||
* @param ColumnMap $cmap A ColumnMap.
|
||||
* @return ColumnMap The added column map.
|
||||
*/
|
||||
public function addConfiguredColumn($cmap)
|
||||
{
|
||||
$this->columns[ $cmap->getColumnName() ] = $cmap;
|
||||
return $cmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this table contain the specified column?
|
||||
*
|
||||
* @param mixed $name name of the column or ColumnMap instance
|
||||
* @param boolean $normalize Normalize the column name (if column name not like FIRST_NAME)
|
||||
* @return boolean True if the table contains the column.
|
||||
*/
|
||||
public function hasColumn($name, $normalize = true)
|
||||
{
|
||||
if ($name instanceof ColumnMap) {
|
||||
$name = $name->getColumnName();
|
||||
} else if($normalize) {
|
||||
$name = ColumnMap::normalizeName($name);
|
||||
}
|
||||
return isset($this->columns[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a ColumnMap for the table.
|
||||
*
|
||||
* @param string $name A String with the name of the table.
|
||||
* @param boolean $normalize Normalize the column name (if column name not like FIRST_NAME)
|
||||
* @return ColumnMap A ColumnMap.
|
||||
* @throws PropelException if the column is undefined
|
||||
*/
|
||||
public function getColumn($name, $normalize = true)
|
||||
{
|
||||
if ($normalize) {
|
||||
$name = ColumnMap::normalizeName($name);
|
||||
}
|
||||
if (!$this->hasColumn($name, false)) {
|
||||
throw new PropelException("Cannot fetch ColumnMap for undefined column: " . $name);
|
||||
}
|
||||
return $this->columns[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this table contain the specified column?
|
||||
*
|
||||
* @param mixed $phpName name of the column
|
||||
* @return boolean True if the table contains the column.
|
||||
*/
|
||||
public function hasColumnByPhpName($phpName)
|
||||
{
|
||||
return isset($this->columnsByPhpName[$phpName]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a ColumnMap for the table.
|
||||
*
|
||||
* @param string $phpName A String with the name of the table.
|
||||
* @return ColumnMap A ColumnMap.
|
||||
* @throws PropelException if the column is undefined
|
||||
*/
|
||||
public function getColumnByPhpName($phpName)
|
||||
{
|
||||
if (!isset($this->columnsByPhpName[$phpName])) {
|
||||
throw new PropelException("Cannot fetch ColumnMap for undefined column phpName: " . $phpName);
|
||||
}
|
||||
return $this->columnsByPhpName[$phpName];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a ColumnMap[] of the columns in this table.
|
||||
*
|
||||
* @return array A ColumnMap[].
|
||||
*/
|
||||
public function getColumns()
|
||||
{
|
||||
return $this->columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a primary key column to this Table.
|
||||
*
|
||||
* @param string $columnName A String with the column name.
|
||||
* @param string $type A string specifying the Propel type.
|
||||
* @param boolean $isNotNull Whether column does not allow NULL values.
|
||||
* @param $size An int specifying the size.
|
||||
* @return ColumnMap Newly added PrimaryKey column.
|
||||
*/
|
||||
public function addPrimaryKey($columnName, $phpName, $type, $isNotNull = false, $size = null, $defaultValue = null)
|
||||
{
|
||||
return $this->addColumn($columnName, $phpName, $type, $isNotNull, $size, $defaultValue, true, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a foreign key column to the table.
|
||||
*
|
||||
* @param string $columnName A String with the column name.
|
||||
* @param string $type A string specifying the Propel type.
|
||||
* @param string $fkTable A String with the foreign key table name.
|
||||
* @param string $fkColumn A String with the foreign key column name.
|
||||
* @param boolean $isNotNull Whether column does not allow NULL values.
|
||||
* @param int $size An int specifying the size.
|
||||
* @param string $defaultValue The default value for this column.
|
||||
* @return ColumnMap Newly added ForeignKey column.
|
||||
*/
|
||||
public function addForeignKey($columnName, $phpName, $type, $fkTable, $fkColumn, $isNotNull = false, $size = 0, $defaultValue = null)
|
||||
{
|
||||
return $this->addColumn($columnName, $phpName, $type, $isNotNull, $size, $defaultValue, false, $fkTable, $fkColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a foreign primary key column to the table.
|
||||
*
|
||||
* @param string $columnName A String with the column name.
|
||||
* @param string $type A string specifying the Propel type.
|
||||
* @param string $fkTable A String with the foreign key table name.
|
||||
* @param string $fkColumn A String with the foreign key column name.
|
||||
* @param boolean $isNotNull Whether column does not allow NULL values.
|
||||
* @param int $size An int specifying the size.
|
||||
* @param string $defaultValue The default value for this column.
|
||||
* @return ColumnMap Newly created foreign pkey column.
|
||||
*/
|
||||
public function addForeignPrimaryKey($columnName, $phpName, $type, $fkTable, $fkColumn, $isNotNull = false, $size = 0, $defaultValue = null)
|
||||
{
|
||||
return $this->addColumn($columnName, $phpName, $type, $isNotNull, $size, $defaultValue, true, $fkTable, $fkColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns array of ColumnMap objects that make up the primary key for this table
|
||||
*
|
||||
* @return array ColumnMap[]
|
||||
*/
|
||||
public function getPrimaryKeys()
|
||||
{
|
||||
return $this->primaryKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns array of ColumnMap objects that are foreign keys for this table
|
||||
*
|
||||
* @return array ColumnMap[]
|
||||
*/
|
||||
public function getForeignKeys()
|
||||
{
|
||||
return $this->foreignKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a validator to a table's column
|
||||
*
|
||||
* @param string $columnName The name of the validator's column
|
||||
* @param string $name The rule name of this validator
|
||||
* @param string $classname The dot-path name of class to use (e.g. myapp.propel.MyValidator)
|
||||
* @param string $value
|
||||
* @param string $message The error message which is returned on invalid values
|
||||
* @return void
|
||||
*/
|
||||
public function addValidator($columnName, $name, $classname, $value, $message)
|
||||
{
|
||||
if (false !== ($pos = strpos($columnName, '.'))) {
|
||||
$columnName = substr($columnName, $pos + 1);
|
||||
}
|
||||
|
||||
$col = $this->getColumn($columnName);
|
||||
if ($col !== null) {
|
||||
$validator = new ValidatorMap($col);
|
||||
$validator->setName($name);
|
||||
$validator->setClass($classname);
|
||||
$validator->setValue($value);
|
||||
$validator->setMessage($message);
|
||||
$col->addValidator($validator);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build relations
|
||||
* Relations are lazy loaded for performance reasons
|
||||
* This method should be overridden by descendents
|
||||
*/
|
||||
public function buildRelations()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a RelationMap to the table
|
||||
*
|
||||
* @param string $name The relation name
|
||||
* @param string $tablePhpName The related table name
|
||||
* @param integer $type The relation type (either RelationMap::MANY_TO_ONE, RelationMap::ONE_TO_MANY, or RelationMAp::ONE_TO_ONE)
|
||||
* @param array $columnMapping An associative array mapping column names (local => foreign)
|
||||
* @return RelationMap the built RelationMap object
|
||||
*/
|
||||
public function addRelation($name, $tablePhpName, $type, $columnMapping = array(), $onDelete = null, $onUpdate = null)
|
||||
{
|
||||
// note: using phpName for the second table allows the use of DatabaseMap::getTableByPhpName()
|
||||
// and this method autoloads the TableMap if the table isn't loaded yet
|
||||
$relation = new RelationMap($name);
|
||||
$relation->setType($type);
|
||||
$relation->setOnUpdate($onUpdate);
|
||||
$relation->setOnDelete($onDelete);
|
||||
// set tables
|
||||
if ($type == RelationMap::MANY_TO_ONE) {
|
||||
$relation->setLocalTable($this);
|
||||
$relation->setForeignTable($this->dbMap->getTableByPhpName($tablePhpName));
|
||||
} else {
|
||||
$relation->setLocalTable($this->dbMap->getTableByPhpName($tablePhpName));
|
||||
$relation->setForeignTable($this);
|
||||
$columnMapping = array_flip($columnMapping);
|
||||
}
|
||||
// set columns
|
||||
foreach ($columnMapping as $local => $foreign) {
|
||||
$relation->addColumnMapping(
|
||||
$relation->getLocalTable()->getColumn($local),
|
||||
$relation->getForeignTable()->getColumn($foreign)
|
||||
);
|
||||
}
|
||||
$this->relations[$name] = $relation;
|
||||
return $relation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a RelationMap of the table by relation name
|
||||
* This method will build the relations if they are not built yet
|
||||
*
|
||||
* @param String $name The relation name
|
||||
* @return boolean true if the relation exists
|
||||
*/
|
||||
public function hasRelation($name)
|
||||
{
|
||||
return array_key_exists($name, $this->getRelations());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a RelationMap of the table by relation name
|
||||
* This method will build the relations if they are not built yet
|
||||
*
|
||||
* @param String $name The relation name
|
||||
* @return RelationMap The relation object
|
||||
* @throws PropelException When called on an inexistent relation
|
||||
*/
|
||||
public function getRelation($name)
|
||||
{
|
||||
if (!array_key_exists($name, $this->getRelations()))
|
||||
{
|
||||
throw new PropelException('Calling getRelation() on an unknown relation, ' . $name);
|
||||
}
|
||||
return $this->relations[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the RelationMap objects of the table
|
||||
* This method will build the relations if they are not built yet
|
||||
*
|
||||
* @return Array list of RelationMap objects
|
||||
*/
|
||||
public function getRelations()
|
||||
{
|
||||
if(!$this->relationsBuilt)
|
||||
{
|
||||
$this->buildRelations();
|
||||
$this->relationsBuilt = true;
|
||||
}
|
||||
return $this->relations;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Gets the list of behaviors registered for this table
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getBehaviors()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
// Deprecated methods and attributres, to be removed
|
||||
|
||||
/**
|
||||
* Does this table contain the specified column?
|
||||
*
|
||||
* @deprecated Use hasColumn instead
|
||||
* @param mixed $name name of the column or ColumnMap instance
|
||||
* @param boolean $normalize Normalize the column name (if column name not like FIRST_NAME)
|
||||
* @return boolean True if the table contains the column.
|
||||
*/
|
||||
public function containsColumn($name, $normalize = true)
|
||||
{
|
||||
return $this->hasColumn($name, $normalize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the column name, removing table prefix and uppercasing.
|
||||
* article.first_name becomes FIRST_NAME
|
||||
*
|
||||
* @deprecated Use ColumnMap::normalizeColumName() instead
|
||||
* @param string $name
|
||||
* @return string Normalized column name.
|
||||
*/
|
||||
protected function normalizeColName($name)
|
||||
{
|
||||
return ColumnMap::normalizeName($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns array of ColumnMap objects that make up the primary key for this table.
|
||||
*
|
||||
* @deprecated Use getPrimaryKeys instead
|
||||
* @return array ColumnMap[]
|
||||
*/
|
||||
public function getPrimaryKeyColumns()
|
||||
{
|
||||
return array_values($this->primaryKeys);
|
||||
}
|
||||
|
||||
//---Utility methods for doing intelligent lookup of table names
|
||||
|
||||
/**
|
||||
* The prefix on the table name.
|
||||
* @deprecated Not used anywhere in Propel
|
||||
*/
|
||||
private $prefix;
|
||||
|
||||
/**
|
||||
* Get table prefix name.
|
||||
*
|
||||
* @deprecated Not used anywhere in Propel
|
||||
* @return string A String with the prefix.
|
||||
*/
|
||||
public function getPrefix()
|
||||
{
|
||||
return $this->prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set table prefix name.
|
||||
*
|
||||
* @deprecated Not used anywhere in Propel
|
||||
* @param string $prefix The prefix for the table name (ie: SCARAB for
|
||||
* SCARAB_PROJECT).
|
||||
* @return void
|
||||
*/
|
||||
public function setPrefix($prefix)
|
||||
{
|
||||
$this->prefix = $prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell me if i have PREFIX in my string.
|
||||
*
|
||||
* @deprecated Not used anywhere in Propel
|
||||
* @param data A String.
|
||||
* @return boolean True if prefix is contained in data.
|
||||
*/
|
||||
protected function hasPrefix($data)
|
||||
{
|
||||
return (strpos($data, $this->prefix) === 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the PREFIX if found
|
||||
*
|
||||
* @deprecated Not used anywhere in Propel
|
||||
* @param string $data A String.
|
||||
* @return string A String with data, but with prefix removed.
|
||||
*/
|
||||
protected function removePrefix($data)
|
||||
{
|
||||
return $this->hasPrefix($data) ? substr($data, strlen($this->prefix)) : $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the PREFIX, removes the underscores and makes
|
||||
* first letter caps.
|
||||
*
|
||||
* SCARAB_FOO_BAR becomes FooBar.
|
||||
*
|
||||
* @deprecated Not used anywhere in Propel. At buildtime, use Column::generatePhpName() for that purpose
|
||||
* @param data A String.
|
||||
* @return string A String with data processed.
|
||||
*/
|
||||
public final function removeUnderScores($data)
|
||||
{
|
||||
$out = '';
|
||||
$tmp = $this->removePrefix($data);
|
||||
$tok = strtok($tmp, '_');
|
||||
while ($tok) {
|
||||
$out .= ucfirst($tok);
|
||||
$tok = strtok('_');
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the first letter caps and the rest lowercase.
|
||||
*
|
||||
* @deprecated Not used anywhere in Propel.
|
||||
* @param string $data A String.
|
||||
* @return string A String with data processed.
|
||||
*/
|
||||
private function firstLetterCaps($data)
|
||||
{
|
||||
return(ucfirst(strtolower($data)));
|
||||
}
|
||||
}
|
92
library/propel/runtime/lib/map/ValidatorMap.php
Normal file
92
library/propel/runtime/lib/map/ValidatorMap.php
Normal file
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* ValidatorMap is used to model a column validator.
|
||||
*
|
||||
* GENERAL NOTE
|
||||
* ------------
|
||||
* The propel.map classes are abstract building-block classes for modeling
|
||||
* the database at runtime. These classes are similar (a lite version) to the
|
||||
* propel.engine.database.model classes, which are build-time modeling classes.
|
||||
* These classes in themselves do not do any database metadata lookups.
|
||||
*
|
||||
* @author Michael Aichler <aichler@mediacluster.de>
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.map
|
||||
*/
|
||||
class ValidatorMap
|
||||
{
|
||||
/** rule name of this validator */
|
||||
private $name;
|
||||
/** the dot-path to class to use for validator */
|
||||
private $classname;
|
||||
/** value to check against */
|
||||
private $value;
|
||||
/** execption message thrown on invalid input */
|
||||
private $message;
|
||||
/** related column */
|
||||
private $column;
|
||||
|
||||
public function __construct($containingColumn)
|
||||
{
|
||||
$this->column = $containingColumn;
|
||||
}
|
||||
|
||||
public function getColumn()
|
||||
{
|
||||
return $this->column;
|
||||
}
|
||||
|
||||
public function getColumnName()
|
||||
{
|
||||
return $this->column->getColumnName();
|
||||
}
|
||||
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function setClass($classname)
|
||||
{
|
||||
$this->classname = $classname;
|
||||
}
|
||||
|
||||
public function setValue($value)
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
public function setMessage($message)
|
||||
{
|
||||
$this->message = $message;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getClass()
|
||||
{
|
||||
return $this->classname;
|
||||
}
|
||||
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
public function getMessage()
|
||||
{
|
||||
return $this->message;
|
||||
}
|
||||
}
|
319
library/propel/runtime/lib/om/BaseObject.php
Normal file
319
library/propel/runtime/lib/om/BaseObject.php
Normal file
|
@ -0,0 +1,319 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class contains attributes and methods that are used by all
|
||||
* business objects within the system.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org> (Propel)
|
||||
* @author Frank Y. Kim <frank.kim@clearink.com> (Torque)
|
||||
* @author John D. McNally <jmcnally@collab.net> (Torque)
|
||||
* @version $Revision: 1673 $
|
||||
* @package propel.runtime.om
|
||||
*/
|
||||
abstract class BaseObject
|
||||
{
|
||||
|
||||
/**
|
||||
* attribute to determine if this object has previously been saved.
|
||||
* @var boolean
|
||||
*/
|
||||
protected $_new = true;
|
||||
|
||||
/**
|
||||
* attribute to determine whether this object has been deleted.
|
||||
* @var boolean
|
||||
*/
|
||||
protected $_deleted = false;
|
||||
|
||||
/**
|
||||
* The columns that have been modified in current object.
|
||||
* Tracking modified columns allows us to only update modified columns.
|
||||
* @var array
|
||||
*/
|
||||
protected $modifiedColumns = array();
|
||||
|
||||
/**
|
||||
* The (virtual) columns that are added at runtime
|
||||
* The formatters can add supplementary columns based on a resultset
|
||||
* @var array
|
||||
*/
|
||||
protected $virtualColumns = array();
|
||||
|
||||
/**
|
||||
* Empty constructor (this allows people with their own BaseObject implementation to use its constructor)
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the object has been modified.
|
||||
*
|
||||
* @return boolean True if the object has been modified.
|
||||
*/
|
||||
public function isModified()
|
||||
{
|
||||
return !empty($this->modifiedColumns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Has specified column been modified?
|
||||
*
|
||||
* @param string $col column fully qualified name (BasePeer::TYPE_COLNAME), e.g. Book::AUTHOR_ID
|
||||
* @return boolean True if $col has been modified.
|
||||
*/
|
||||
public function isColumnModified($col)
|
||||
{
|
||||
return in_array($col, $this->modifiedColumns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the columns that have been modified in this object.
|
||||
* @return array A unique list of the modified column names for this object.
|
||||
*/
|
||||
public function getModifiedColumns()
|
||||
{
|
||||
return array_unique($this->modifiedColumns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the object has ever been saved. This will
|
||||
* be false, if the object was retrieved from storage or was created
|
||||
* and then saved.
|
||||
*
|
||||
* @return true, if the object has never been persisted.
|
||||
*/
|
||||
public function isNew()
|
||||
{
|
||||
return $this->_new;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the isNew attribute. This method will be called
|
||||
* by Propel-generated children and Peers.
|
||||
*
|
||||
* @param boolean $b the state of the object.
|
||||
*/
|
||||
public function setNew($b)
|
||||
{
|
||||
$this->_new = (boolean) $b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this object has been deleted.
|
||||
* @return boolean The deleted state of this object.
|
||||
*/
|
||||
public function isDeleted()
|
||||
{
|
||||
return $this->_deleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify whether this object has been deleted.
|
||||
* @param boolean $b The deleted state of this object.
|
||||
* @return void
|
||||
*/
|
||||
public function setDeleted($b)
|
||||
{
|
||||
$this->_deleted = (boolean) $b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Code to be run before persisting the object
|
||||
* @param PropelPDO $con
|
||||
* @return bloolean
|
||||
*/
|
||||
public function preSave(PropelPDO $con = null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Code to be run after persisting the object
|
||||
* @param PropelPDO $con
|
||||
*/
|
||||
public function postSave(PropelPDO $con = null) { }
|
||||
|
||||
/**
|
||||
* Code to be run before inserting to database
|
||||
* @param PropelPDO $con
|
||||
* @return boolean
|
||||
*/
|
||||
public function preInsert(PropelPDO $con = null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Code to be run after inserting to database
|
||||
* @param PropelPDO $con
|
||||
*/
|
||||
public function postInsert(PropelPDO $con = null) { }
|
||||
|
||||
/**
|
||||
* Code to be run before updating the object in database
|
||||
* @param PropelPDO $con
|
||||
* @return boolean
|
||||
*/
|
||||
public function preUpdate(PropelPDO $con = null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Code to be run after updating the object in database
|
||||
* @param PropelPDO $con
|
||||
*/
|
||||
public function postUpdate(PropelPDO $con = null) { }
|
||||
|
||||
/**
|
||||
* Code to be run before deleting the object in database
|
||||
* @param PropelPDO $con
|
||||
* @return boolean
|
||||
*/
|
||||
public function preDelete(PropelPDO $con = null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Code to be run after deleting the object in database
|
||||
* @param PropelPDO $con
|
||||
*/
|
||||
public function postDelete(PropelPDO $con = null) { }
|
||||
|
||||
/**
|
||||
* Sets the modified state for the object to be false.
|
||||
* @param string $col If supplied, only the specified column is reset.
|
||||
* @return void
|
||||
*/
|
||||
public function resetModified($col = null)
|
||||
{
|
||||
if ($col !== null) {
|
||||
while (($offset = array_search($col, $this->modifiedColumns)) !== false) {
|
||||
array_splice($this->modifiedColumns, $offset, 1);
|
||||
}
|
||||
} else {
|
||||
$this->modifiedColumns = array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this with another <code>BaseObject</code> instance. If
|
||||
* <code>obj</code> is an instance of <code>BaseObject</code>, delegates to
|
||||
* <code>equals(BaseObject)</code>. Otherwise, returns <code>false</code>.
|
||||
*
|
||||
* @param obj The object to compare to.
|
||||
* @return Whether equal to the object specified.
|
||||
*/
|
||||
public function equals($obj)
|
||||
{
|
||||
$thisclazz = get_class($this);
|
||||
if (is_object($obj) && $obj instanceof $thisclazz) {
|
||||
if ($this === $obj) {
|
||||
return true;
|
||||
} elseif ($this->getPrimaryKey() === null || $obj->getPrimaryKey() === null) {
|
||||
return false;
|
||||
} else {
|
||||
return ($this->getPrimaryKey() === $obj->getPrimaryKey());
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the primary key is not <code>null</code>, return the hashcode of the
|
||||
* primary key. Otherwise calls <code>Object.hashCode()</code>.
|
||||
*
|
||||
* @return int Hashcode
|
||||
*/
|
||||
public function hashCode()
|
||||
{
|
||||
$ok = $this->getPrimaryKey();
|
||||
if ($ok === null) {
|
||||
return crc32(serialize($this));
|
||||
}
|
||||
return crc32(serialize($ok)); // serialize because it could be an array ("ComboKey")
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the associative array of the virtual columns in this object
|
||||
*
|
||||
* @param string $name The virtual column name
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getVirtualColumns()
|
||||
{
|
||||
return $this->virtualColumns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the existence of a virtual column in this object
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasVirtualColumn($name)
|
||||
{
|
||||
return array_key_exists($name, $this->virtualColumns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of a virtual column in this object
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getVirtualColumn($name)
|
||||
{
|
||||
if (!$this->hasVirtualColumn($name)) {
|
||||
throw new PropelException('Cannot get value of inexistent virtual column ' . $name);
|
||||
}
|
||||
return $this->virtualColumns[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of a virtual column in this object
|
||||
*
|
||||
* @param string $name The virtual column name
|
||||
* @param mixed $value The value to give to the virtual column
|
||||
*
|
||||
* @return BaseObject The current object, for fluid interface
|
||||
*/
|
||||
public function setVirtualColumn($name, $value)
|
||||
{
|
||||
$this->virtualColumns[$name] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a message using Propel::log().
|
||||
*
|
||||
* @param string $msg
|
||||
* @param int $priority One of the Propel::LOG_* logging levels
|
||||
* @return boolean
|
||||
*/
|
||||
protected function log($msg, $priority = Propel::LOG_INFO)
|
||||
{
|
||||
return Propel::log(get_class($this) . ': ' . $msg, $priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up internal collections prior to serializing
|
||||
* Avoids recursive loops that turn into segmentation faults when serializing
|
||||
*/
|
||||
public function __sleep()
|
||||
{
|
||||
$this->clearAllReferences();
|
||||
return array_keys(get_object_vars($this));
|
||||
}
|
||||
|
||||
}
|
86
library/propel/runtime/lib/om/NestedSetRecursiveIterator.php
Normal file
86
library/propel/runtime/lib/om/NestedSetRecursiveIterator.php
Normal file
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Pre-order node iterator for Node objects.
|
||||
*
|
||||
* @author Heltem <heltem@o2php.com>
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.om
|
||||
*/
|
||||
class NestedSetRecursiveIterator implements RecursiveIterator
|
||||
{
|
||||
protected $topNode = null;
|
||||
|
||||
protected $curNode = null;
|
||||
|
||||
public function __construct($node)
|
||||
{
|
||||
$this->topNode = $node;
|
||||
$this->curNode = $node;
|
||||
}
|
||||
|
||||
public function rewind()
|
||||
{
|
||||
$this->curNode = $this->topNode;
|
||||
}
|
||||
|
||||
public function valid()
|
||||
{
|
||||
return ($this->curNode !== null);
|
||||
}
|
||||
|
||||
public function current()
|
||||
{
|
||||
return $this->curNode;
|
||||
}
|
||||
|
||||
public function key()
|
||||
{
|
||||
$method = method_exists($this->curNode, 'getPath') ? 'getPath' : 'getAncestors';
|
||||
$key = array();
|
||||
foreach ($this->curNode->$method() as $node) {
|
||||
$key[] = $node->getPrimaryKey();
|
||||
}
|
||||
return implode('.', $key);
|
||||
}
|
||||
|
||||
public function next()
|
||||
{
|
||||
$nextNode = null;
|
||||
$method = method_exists($this->curNode, 'retrieveNextSibling') ? 'retrieveNextSibling' : 'getNextSibling';
|
||||
if ($this->valid()) {
|
||||
while (null === $nextNode) {
|
||||
if (null === $this->curNode) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ($this->curNode->hasNextSibling()) {
|
||||
$nextNode = $this->curNode->$method();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->curNode = $nextNode;
|
||||
}
|
||||
return $this->curNode;
|
||||
}
|
||||
|
||||
public function hasChildren()
|
||||
{
|
||||
return $this->curNode->hasChildren();
|
||||
}
|
||||
|
||||
public function getChildren()
|
||||
{
|
||||
$method = method_exists($this->curNode, 'retrieveFirstChild') ? 'retrieveFirstChild' : 'getFirstChild';
|
||||
return new NestedSetRecursiveIterator($this->curNode->$method());
|
||||
}
|
||||
}
|
324
library/propel/runtime/lib/om/NodeObject.php
Normal file
324
library/propel/runtime/lib/om/NodeObject.php
Normal file
|
@ -0,0 +1,324 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* This interface defines methods that must be implemented by all
|
||||
* business objects within the system to handle Node object.
|
||||
*
|
||||
* @author Heltem <heltem@o2php.com> (Propel)
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.om
|
||||
*/
|
||||
interface NodeObject extends IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* If object is saved without left/right values, set them as undefined (0)
|
||||
*
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return void
|
||||
* @throws PropelException
|
||||
*/
|
||||
public function save(PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Delete node and descendants
|
||||
*
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return void
|
||||
* @throws PropelException
|
||||
*/
|
||||
public function delete(PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Sets node properties to make it a root node.
|
||||
*
|
||||
* @return object The current object (for fluent API support)
|
||||
* @throws PropelException
|
||||
*/
|
||||
public function makeRoot();
|
||||
|
||||
/**
|
||||
* Gets the level if set, otherwise calculates this and returns it
|
||||
*
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return int
|
||||
*/
|
||||
public function getLevel(PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Get the path to the node in the tree
|
||||
*
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return array
|
||||
*/
|
||||
public function getPath(PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Gets the number of children for the node (direct descendants)
|
||||
*
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return int
|
||||
*/
|
||||
public function getNumberOfChildren(PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Gets the total number of desceandants for the node
|
||||
*
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return int
|
||||
*/
|
||||
public function getNumberOfDescendants(PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Gets the children for the node
|
||||
*
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return array
|
||||
*/
|
||||
public function getChildren(PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Gets the descendants for the node
|
||||
*
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return array
|
||||
*/
|
||||
public function getDescendants(PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Sets the level of the node in the tree
|
||||
*
|
||||
* @param int $v new value
|
||||
* @return object The current object (for fluent API support)
|
||||
*/
|
||||
public function setLevel($level);
|
||||
|
||||
/**
|
||||
* Sets the children array of the node in the tree
|
||||
*
|
||||
* @param array of Node $children array of Propel node object
|
||||
* @return object The current object (for fluent API support)
|
||||
*/
|
||||
public function setChildren(array $children);
|
||||
|
||||
/**
|
||||
* Sets the parentNode of the node in the tree
|
||||
*
|
||||
* @param Node $parent Propel node object
|
||||
* @return object The current object (for fluent API support)
|
||||
*/
|
||||
public function setParentNode(NodeObject $parent = null);
|
||||
|
||||
/**
|
||||
* Sets the previous sibling of the node in the tree
|
||||
*
|
||||
* @param Node $node Propel node object
|
||||
* @return object The current object (for fluent API support)
|
||||
*/
|
||||
public function setPrevSibling(NodeObject $node = null);
|
||||
|
||||
/**
|
||||
* Sets the next sibling of the node in the tree
|
||||
*
|
||||
* @param Node $node Propel node object
|
||||
* @return object The current object (for fluent API support)
|
||||
*/
|
||||
public function setNextSibling(NodeObject $node = null);
|
||||
|
||||
/**
|
||||
* Determines if the node is the root node
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isRoot();
|
||||
|
||||
/**
|
||||
* Determines if the node is a leaf node
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isLeaf();
|
||||
|
||||
/**
|
||||
* Tests if object is equal to $node
|
||||
*
|
||||
* @param object $node Propel object for node to compare to
|
||||
* @return bool
|
||||
*/
|
||||
public function isEqualTo(NodeObject $node);
|
||||
|
||||
/**
|
||||
* Tests if object has an ancestor
|
||||
*
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return bool
|
||||
*/
|
||||
public function hasParent(PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Determines if the node has children / descendants
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasChildren();
|
||||
|
||||
/**
|
||||
* Determines if the node has previous sibling
|
||||
*
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return bool
|
||||
*/
|
||||
public function hasPrevSibling(PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Determines if the node has next sibling
|
||||
*
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return bool
|
||||
*/
|
||||
public function hasNextSibling(PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Gets ancestor for the given node if it exists
|
||||
*
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return mixed Propel object if exists else false
|
||||
*/
|
||||
public function retrieveParent(PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Gets first child if it exists
|
||||
*
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return mixed Propel object if exists else false
|
||||
*/
|
||||
public function retrieveFirstChild(PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Gets last child if it exists
|
||||
*
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return mixed Propel object if exists else false
|
||||
*/
|
||||
public function retrieveLastChild(PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Gets prev sibling for the given node if it exists
|
||||
*
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return mixed Propel object if exists else false
|
||||
*/
|
||||
public function retrievePrevSibling(PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Gets next sibling for the given node if it exists
|
||||
*
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return mixed Propel object if exists else false
|
||||
*/
|
||||
public function retrieveNextSibling(PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Inserts as first child of destination node $parent
|
||||
*
|
||||
* @param object $parent Propel object for given destination node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return object The current object (for fluent API support)
|
||||
*/
|
||||
public function insertAsFirstChildOf(NodeObject $parent, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Inserts as last child of destination node $parent
|
||||
*
|
||||
* @param object $parent Propel object for given destination node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return object The current object (for fluent API support)
|
||||
*/
|
||||
public function insertAsLastChildOf(NodeObject $parent, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Inserts node as previous sibling to destination node $dest
|
||||
*
|
||||
* @param object $dest Propel object for given destination node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return object The current object (for fluent API support)
|
||||
*/
|
||||
public function insertAsPrevSiblingOf(NodeObject $dest, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Inserts node as next sibling to destination node $dest
|
||||
*
|
||||
* @param object $dest Propel object for given destination node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return object The current object (for fluent API support)
|
||||
*/
|
||||
public function insertAsNextSiblingOf(NodeObject $dest, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Moves node to be first child of $parent
|
||||
*
|
||||
* @param object $parent Propel object for destination node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return void
|
||||
*/
|
||||
public function moveToFirstChildOf(NodeObject $parent, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Moves node to be last child of $parent
|
||||
*
|
||||
* @param object $parent Propel object for destination node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return void
|
||||
*/
|
||||
public function moveToLastChildOf(NodeObject $parent, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Moves node to be prev sibling to $dest
|
||||
*
|
||||
* @param object $dest Propel object for destination node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return void
|
||||
*/
|
||||
public function moveToPrevSiblingOf(NodeObject $dest, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Moves node to be next sibling to $dest
|
||||
*
|
||||
* @param object $dest Propel object for destination node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return void
|
||||
*/
|
||||
public function moveToNextSiblingOf(NodeObject $dest, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Inserts node as parent of given node.
|
||||
*
|
||||
* @param object $node Propel object for given destination node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return void
|
||||
* @throws Exception When trying to insert node as parent of a root node
|
||||
*/
|
||||
public function insertAsParentOf(NodeObject $node, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Wraps the getter for the scope value
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getScopeIdValue();
|
||||
|
||||
/**
|
||||
* Set the value of scope column
|
||||
*
|
||||
* @param int $v new value
|
||||
* @return object The current object (for fluent API support)
|
||||
*/
|
||||
public function setScopeIdValue($v);
|
||||
} // NodeObject
|
108
library/propel/runtime/lib/om/Persistent.php
Normal file
108
library/propel/runtime/lib/om/Persistent.php
Normal file
|
@ -0,0 +1,108 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* This interface defines methods related to saving an object
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org> (Propel)
|
||||
* @author John D. McNally <jmcnally@collab.net> (Torque)
|
||||
* @author Fedor K. <fedor@apache.org> (Torque)
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.om
|
||||
*/
|
||||
interface Persistent
|
||||
{
|
||||
|
||||
/**
|
||||
* getter for the object primaryKey.
|
||||
*
|
||||
* @return ObjectKey the object primaryKey as an Object
|
||||
*/
|
||||
public function getPrimaryKey();
|
||||
|
||||
/**
|
||||
* Sets the PrimaryKey for the object.
|
||||
*
|
||||
* @param mixed $primaryKey The new PrimaryKey object or string (result of PrimaryKey.toString()).
|
||||
* @return void
|
||||
* @throws Exception, This method might throw an exceptions
|
||||
*/
|
||||
public function setPrimaryKey($primaryKey);
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether the object has been modified, since it was
|
||||
* last retrieved from storage.
|
||||
*
|
||||
* @return boolean True if the object has been modified.
|
||||
*/
|
||||
public function isModified();
|
||||
|
||||
/**
|
||||
* Has specified column been modified?
|
||||
*
|
||||
* @param string $col
|
||||
* @return boolean True if $col has been modified.
|
||||
*/
|
||||
public function isColumnModified($col);
|
||||
|
||||
/**
|
||||
* Returns whether the object has ever been saved. This will
|
||||
* be false, if the object was retrieved from storage or was created
|
||||
* and then saved.
|
||||
*
|
||||
* @return boolean True, if the object has never been persisted.
|
||||
*/
|
||||
public function isNew();
|
||||
|
||||
/**
|
||||
* Setter for the isNew attribute. This method will be called
|
||||
* by Propel-generated children and Peers.
|
||||
*
|
||||
* @param boolean $b the state of the object.
|
||||
*/
|
||||
public function setNew($b);
|
||||
|
||||
/**
|
||||
* Resets (to false) the "modified" state for this object.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function resetModified();
|
||||
|
||||
/**
|
||||
* Whether this object has been deleted.
|
||||
* @return boolean The deleted state of this object.
|
||||
*/
|
||||
public function isDeleted();
|
||||
|
||||
/**
|
||||
* Specify whether this object has been deleted.
|
||||
* @param boolean $b The deleted state of this object.
|
||||
* @return void
|
||||
*/
|
||||
public function setDeleted($b);
|
||||
|
||||
/**
|
||||
* Deletes the object.
|
||||
* @param PropelPDO $con
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
public function delete(PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Saves the object.
|
||||
* @param PropelPDO $con
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
public function save(PropelPDO $con = null);
|
||||
}
|
78
library/propel/runtime/lib/om/PreOrderNodeIterator.php
Normal file
78
library/propel/runtime/lib/om/PreOrderNodeIterator.php
Normal file
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Pre-order node iterator for Node objects.
|
||||
*
|
||||
* @author Dave Lawson <dlawson@masterytech.com>
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.om
|
||||
*/
|
||||
class PreOrderNodeIterator implements Iterator
|
||||
{
|
||||
private $topNode = null;
|
||||
|
||||
private $curNode = null;
|
||||
|
||||
private $querydb = false;
|
||||
|
||||
private $con = null;
|
||||
|
||||
public function __construct($node, $opts) {
|
||||
$this->topNode = $node;
|
||||
$this->curNode = $node;
|
||||
|
||||
if (isset($opts['con']))
|
||||
$this->con = $opts['con'];
|
||||
|
||||
if (isset($opts['querydb']))
|
||||
$this->querydb = $opts['querydb'];
|
||||
}
|
||||
|
||||
public function rewind() {
|
||||
$this->curNode = $this->topNode;
|
||||
}
|
||||
|
||||
public function valid() {
|
||||
return ($this->curNode !== null);
|
||||
}
|
||||
|
||||
public function current() {
|
||||
return $this->curNode;
|
||||
}
|
||||
|
||||
public function key() {
|
||||
return $this->curNode->getNodePath();
|
||||
}
|
||||
|
||||
public function next() {
|
||||
|
||||
if ($this->valid())
|
||||
{
|
||||
$nextNode = $this->curNode->getFirstChildNode($this->querydb, $this->con);
|
||||
|
||||
while ($nextNode === null)
|
||||
{
|
||||
if ($this->curNode === null || $this->curNode->equals($this->topNode))
|
||||
break;
|
||||
|
||||
$nextNode = $this->curNode->getSiblingNode(false, $this->querydb, $this->con);
|
||||
|
||||
if ($nextNode === null)
|
||||
$this->curNode = $this->curNode->getParentNode($this->querydb, $this->con);
|
||||
}
|
||||
|
||||
$this->curNode = $nextNode;
|
||||
}
|
||||
|
||||
return $this->curNode;
|
||||
}
|
||||
|
||||
}
|
1561
library/propel/runtime/lib/query/Criteria.php
Normal file
1561
library/propel/runtime/lib/query/Criteria.php
Normal file
File diff suppressed because it is too large
Load diff
543
library/propel/runtime/lib/query/Criterion.php
Normal file
543
library/propel/runtime/lib/query/Criterion.php
Normal file
|
@ -0,0 +1,543 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is an "inner" class that describes an object in the criteria.
|
||||
*
|
||||
* In Torque this is an inner class of the Criteria class.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org> (Propel)
|
||||
* @version $Revision: 1740 $
|
||||
* @package propel.runtime.query
|
||||
*/
|
||||
class Criterion
|
||||
{
|
||||
|
||||
const UND = " AND ";
|
||||
const ODER = " OR ";
|
||||
|
||||
/** Value of the CO. */
|
||||
protected $value;
|
||||
|
||||
/** Comparison value.
|
||||
* @var SqlEnum
|
||||
*/
|
||||
protected $comparison;
|
||||
|
||||
/** Table name. */
|
||||
protected $table;
|
||||
|
||||
/** Real table name */
|
||||
protected $realtable;
|
||||
|
||||
/** Column name. */
|
||||
protected $column;
|
||||
|
||||
/** flag to ignore case in comparison */
|
||||
protected $ignoreStringCase = false;
|
||||
|
||||
/**
|
||||
* The DBAdaptor which might be used to get db specific
|
||||
* variations of sql.
|
||||
*/
|
||||
protected $db;
|
||||
|
||||
/**
|
||||
* other connected criteria and their conjunctions.
|
||||
*/
|
||||
protected $clauses = array();
|
||||
protected $conjunctions = array();
|
||||
|
||||
/** "Parent" Criteria class */
|
||||
protected $parent;
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param Criteria $parent The outer class (this is an "inner" class).
|
||||
* @param string $column TABLE.COLUMN format.
|
||||
* @param mixed $value
|
||||
* @param string $comparison
|
||||
*/
|
||||
public function __construct(Criteria $outer, $column, $value, $comparison = null)
|
||||
{
|
||||
$this->value = $value;
|
||||
$dotPos = strrpos($column, '.');
|
||||
if ($dotPos === false) {
|
||||
// no dot => aliased column
|
||||
$this->table = null;
|
||||
$this->column = $column;
|
||||
} else {
|
||||
$this->table = substr($column, 0, $dotPos);
|
||||
$this->column = substr($column, $dotPos + 1);
|
||||
}
|
||||
$this->comparison = ($comparison === null) ? Criteria::EQUAL : $comparison;
|
||||
$this->init($outer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Init some properties with the help of outer class
|
||||
* @param Criteria $criteria The outer class
|
||||
*/
|
||||
public function init(Criteria $criteria)
|
||||
{
|
||||
// init $this->db
|
||||
try {
|
||||
$db = Propel::getDB($criteria->getDbName());
|
||||
$this->setDB($db);
|
||||
} catch (Exception $e) {
|
||||
// we are only doing this to allow easier debugging, so
|
||||
// no need to throw up the exception, just make note of it.
|
||||
Propel::log("Could not get a DBAdapter, sql may be wrong", Propel::LOG_ERR);
|
||||
}
|
||||
|
||||
// init $this->realtable
|
||||
$realtable = $criteria->getTableForAlias($this->table);
|
||||
$this->realtable = $realtable ? $realtable : $this->table;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the column name.
|
||||
*
|
||||
* @return string A String with the column name.
|
||||
*/
|
||||
public function getColumn()
|
||||
{
|
||||
return $this->column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the table name.
|
||||
*
|
||||
* @param name A String with the table name.
|
||||
* @return void
|
||||
*/
|
||||
public function setTable($name)
|
||||
{
|
||||
$this->table = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the table name.
|
||||
*
|
||||
* @return string A String with the table name.
|
||||
*/
|
||||
public function getTable()
|
||||
{
|
||||
return $this->table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the comparison.
|
||||
*
|
||||
* @return string A String with the comparison.
|
||||
*/
|
||||
public function getComparison()
|
||||
{
|
||||
return $this->comparison;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value.
|
||||
*
|
||||
* @return mixed An Object with the value.
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of db.
|
||||
* The DBAdapter which might be used to get db specific
|
||||
* variations of sql.
|
||||
* @return DBAdapter value of db.
|
||||
*/
|
||||
public function getDB()
|
||||
{
|
||||
return $this->db;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of db.
|
||||
* The DBAdapter might be used to get db specific variations of sql.
|
||||
* @param DBAdapter $v Value to assign to db.
|
||||
* @return void
|
||||
*/
|
||||
public function setDB(DBAdapter $v)
|
||||
{
|
||||
$this->db = $v;
|
||||
foreach ( $this->clauses as $clause ) {
|
||||
$clause->setDB($v);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets ignore case.
|
||||
*
|
||||
* @param boolean $b True if case should be ignored.
|
||||
* @return Criterion A modified Criterion object.
|
||||
*/
|
||||
public function setIgnoreCase($b)
|
||||
{
|
||||
$this->ignoreStringCase = (boolean) $b;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is ignore case on or off?
|
||||
*
|
||||
* @return boolean True if case is ignored.
|
||||
*/
|
||||
public function isIgnoreCase()
|
||||
{
|
||||
return $this->ignoreStringCase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of clauses in this Criterion.
|
||||
* @return array
|
||||
*/
|
||||
private function getClauses()
|
||||
{
|
||||
return $this->clauses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of conjunctions in this Criterion
|
||||
* @return array
|
||||
*/
|
||||
public function getConjunctions()
|
||||
{
|
||||
return $this->conjunctions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append an AND Criterion onto this Criterion's list.
|
||||
*/
|
||||
public function addAnd(Criterion $criterion)
|
||||
{
|
||||
$this->clauses[] = $criterion;
|
||||
$this->conjunctions[] = self::UND;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append an OR Criterion onto this Criterion's list.
|
||||
* @return Criterion
|
||||
*/
|
||||
public function addOr(Criterion $criterion)
|
||||
{
|
||||
$this->clauses[] = $criterion;
|
||||
$this->conjunctions[] = self::ODER;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a Prepared Statement representation of the Criterion
|
||||
* onto the buffer.
|
||||
*
|
||||
* @param string &$sb The string that will receive the Prepared Statement
|
||||
* @param array $params A list to which Prepared Statement parameters will be appended
|
||||
* @return void
|
||||
* @throws PropelException - if the expression builder cannot figure out how to turn a specified
|
||||
* expression into proper SQL.
|
||||
*/
|
||||
public function appendPsTo(&$sb, array &$params)
|
||||
{
|
||||
$sb .= str_repeat ( '(', count($this->clauses) );
|
||||
|
||||
$this->dispatchPsHandling($sb, $params);
|
||||
|
||||
foreach ($this->clauses as $key => $clause) {
|
||||
$sb .= $this->conjunctions[$key];
|
||||
$clause->appendPsTo($sb, $params);
|
||||
$sb .= ')';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Figure out which Criterion method to use
|
||||
* to build the prepared statement and parameters using to the Criterion comparison
|
||||
* and call it to append the prepared statement and the parameters of the current clause
|
||||
*
|
||||
* @param string &$sb The string that will receive the Prepared Statement
|
||||
* @param array $params A list to which Prepared Statement parameters will be appended
|
||||
*/
|
||||
protected function dispatchPsHandling(&$sb, array &$params)
|
||||
{
|
||||
switch ($this->comparison) {
|
||||
case Criteria::CUSTOM:
|
||||
// custom expression with no parameter binding
|
||||
$this->appendCustomToPs($sb, $params);
|
||||
break;
|
||||
case Criteria::IN:
|
||||
case Criteria::NOT_IN:
|
||||
// table.column IN (?, ?) or table.column NOT IN (?, ?)
|
||||
$this->appendInToPs($sb, $params);
|
||||
break;
|
||||
case Criteria::LIKE:
|
||||
case Criteria::NOT_LIKE:
|
||||
case Criteria::ILIKE:
|
||||
case Criteria::NOT_ILIKE:
|
||||
// table.column LIKE ? or table.column NOT LIKE ? (or ILIKE for Postgres)
|
||||
$this->appendLikeToPs($sb, $params);
|
||||
break;
|
||||
default:
|
||||
// table.column = ? or table.column >= ? etc. (traditional expressions, the default)
|
||||
$this->appendBasicToPs($sb, $params);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a Prepared Statement representation of the Criterion onto the buffer
|
||||
* For custom expressions with no binding, e.g. 'NOW() = 1'
|
||||
*
|
||||
* @param string &$sb The string that will receive the Prepared Statement
|
||||
* @param array $params A list to which Prepared Statement parameters will be appended
|
||||
*/
|
||||
protected function appendCustomToPs(&$sb, array &$params)
|
||||
{
|
||||
if ($this->value !== "") {
|
||||
$sb .= (string) $this->value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a Prepared Statement representation of the Criterion onto the buffer
|
||||
* For IN expressions, e.g. table.column IN (?, ?) or table.column NOT IN (?, ?)
|
||||
*
|
||||
* @param string &$sb The string that will receive the Prepared Statement
|
||||
* @param array $params A list to which Prepared Statement parameters will be appended
|
||||
*/
|
||||
protected function appendInToPs(&$sb, array &$params)
|
||||
{
|
||||
if ($this->value !== "") {
|
||||
$bindParams = array();
|
||||
$index = count($params); // to avoid counting the number of parameters for each element in the array
|
||||
foreach ((array) $this->value as $value) {
|
||||
$params[] = array('table' => $this->realtable, 'column' => $this->column, 'value' => $value);
|
||||
$index++; // increment this first to correct for wanting bind params to start with :p1
|
||||
$bindParams[] = ':p' . $index;
|
||||
}
|
||||
if (count($bindParams)) {
|
||||
$field = ($this->table === null) ? $this->column : $this->table . '.' . $this->column;
|
||||
$sb .= $field . $this->comparison . '(' . implode(',', $bindParams) . ')';
|
||||
} else {
|
||||
$sb .= ($this->comparison === Criteria::IN) ? "1<>1" : "1=1";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a Prepared Statement representation of the Criterion onto the buffer
|
||||
* For LIKE expressions, e.g. table.column LIKE ? or table.column NOT LIKE ? (or ILIKE for Postgres)
|
||||
*
|
||||
* @param string &$sb The string that will receive the Prepared Statement
|
||||
* @param array $params A list to which Prepared Statement parameters will be appended
|
||||
*/
|
||||
protected function appendLikeToPs(&$sb, array &$params)
|
||||
{
|
||||
$field = ($this->table === null) ? $this->column : $this->table . '.' . $this->column;
|
||||
$db = $this->getDb();
|
||||
// If selection is case insensitive use ILIKE for PostgreSQL or SQL
|
||||
// UPPER() function on column name for other databases.
|
||||
if ($this->ignoreStringCase) {
|
||||
if ($db instanceof DBPostgres) {
|
||||
if ($this->comparison === Criteria::LIKE) {
|
||||
$this->comparison = Criteria::ILIKE;
|
||||
} elseif ($this->comparison === Criteria::NOT_LIKE) {
|
||||
$this->comparison = Criteria::NOT_ILIKE;
|
||||
}
|
||||
} else {
|
||||
$field = $db->ignoreCase($field);
|
||||
}
|
||||
}
|
||||
|
||||
$params[] = array('table' => $this->realtable, 'column' => $this->column, 'value' => $this->value);
|
||||
|
||||
$sb .= $field . $this->comparison;
|
||||
|
||||
// If selection is case insensitive use SQL UPPER() function
|
||||
// on criteria or, if Postgres we are using ILIKE, so not necessary.
|
||||
if ($this->ignoreStringCase && !($db instanceof DBPostgres)) {
|
||||
$sb .= $db->ignoreCase(':p'.count($params));
|
||||
} else {
|
||||
$sb .= ':p'.count($params);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a Prepared Statement representation of the Criterion onto the buffer
|
||||
* For traditional expressions, e.g. table.column = ? or table.column >= ? etc.
|
||||
*
|
||||
* @param string &$sb The string that will receive the Prepared Statement
|
||||
* @param array $params A list to which Prepared Statement parameters will be appended
|
||||
*/
|
||||
protected function appendBasicToPs(&$sb, array &$params)
|
||||
{
|
||||
$field = ($this->table === null) ? $this->column : $this->table . '.' . $this->column;
|
||||
// NULL VALUES need special treatment because the SQL syntax is different
|
||||
// i.e. table.column IS NULL rather than table.column = null
|
||||
if ($this->value !== null) {
|
||||
|
||||
// ANSI SQL functions get inserted right into SQL (not escaped, etc.)
|
||||
if ($this->value === Criteria::CURRENT_DATE || $this->value === Criteria::CURRENT_TIME || $this->value === Criteria::CURRENT_TIMESTAMP) {
|
||||
$sb .= $field . $this->comparison . $this->value;
|
||||
} else {
|
||||
|
||||
$params[] = array('table' => $this->realtable, 'column' => $this->column, 'value' => $this->value);
|
||||
|
||||
// default case, it is a normal col = value expression; value
|
||||
// will be replaced w/ '?' and will be inserted later using PDO bindValue()
|
||||
if ($this->ignoreStringCase) {
|
||||
$sb .= $this->getDb()->ignoreCase($field) . $this->comparison . $this->getDb()->ignoreCase(':p'.count($params));
|
||||
} else {
|
||||
$sb .= $field . $this->comparison . ':p'.count($params);
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
|
||||
// value is null, which means it was either not specified or specifically
|
||||
// set to null.
|
||||
if ($this->comparison === Criteria::EQUAL || $this->comparison === Criteria::ISNULL) {
|
||||
$sb .= $field . Criteria::ISNULL;
|
||||
} elseif ($this->comparison === Criteria::NOT_EQUAL || $this->comparison === Criteria::ISNOTNULL) {
|
||||
$sb .= $field . Criteria::ISNOTNULL;
|
||||
} else {
|
||||
// for now throw an exception, because not sure how to interpret this
|
||||
throw new PropelException("Could not build SQL for expression: $field " . $this->comparison . " NULL");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks another Criteria to see if they contain
|
||||
* the same attributes and hashtable entries.
|
||||
* @return boolean
|
||||
*/
|
||||
public function equals($obj)
|
||||
{
|
||||
// TODO: optimize me with early outs
|
||||
if ($this === $obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (($obj === null) || !($obj instanceof Criterion)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$crit = $obj;
|
||||
|
||||
$isEquiv = ( ( ($this->table === null && $crit->getTable() === null)
|
||||
|| ( $this->table !== null && $this->table === $crit->getTable() )
|
||||
)
|
||||
&& $this->column === $crit->getColumn()
|
||||
&& $this->comparison === $crit->getComparison());
|
||||
|
||||
// check chained criterion
|
||||
|
||||
$clausesLength = count($this->clauses);
|
||||
$isEquiv &= (count($crit->getClauses()) == $clausesLength);
|
||||
$critConjunctions = $crit->getConjunctions();
|
||||
$critClauses = $crit->getClauses();
|
||||
for ($i=0; $i < $clausesLength && $isEquiv; $i++) {
|
||||
$isEquiv &= ($this->conjunctions[$i] === $critConjunctions[$i]);
|
||||
$isEquiv &= ($this->clauses[$i] === $critClauses[$i]);
|
||||
}
|
||||
|
||||
if ($isEquiv) {
|
||||
$isEquiv &= $this->value === $crit->getValue();
|
||||
}
|
||||
|
||||
return $isEquiv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash code value for the object.
|
||||
*/
|
||||
public function hashCode()
|
||||
{
|
||||
$h = crc32(serialize($this->value)) ^ crc32($this->comparison);
|
||||
|
||||
if ($this->table !== null) {
|
||||
$h ^= crc32($this->table);
|
||||
}
|
||||
|
||||
if ($this->column !== null) {
|
||||
$h ^= crc32($this->column);
|
||||
}
|
||||
|
||||
foreach ( $this->clauses as $clause ) {
|
||||
// TODO: i KNOW there is a php incompatibility with the following line
|
||||
// but i dont remember what it is, someone care to look it up and
|
||||
// replace it if it doesnt bother us?
|
||||
// $clause->appendPsTo($sb='',$params=array());
|
||||
$sb = '';
|
||||
$params = array();
|
||||
$clause->appendPsTo($sb,$params);
|
||||
$h ^= crc32(serialize(array($sb,$params)));
|
||||
unset ( $sb, $params );
|
||||
}
|
||||
|
||||
return $h;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all tables from nested criterion objects
|
||||
* @return array
|
||||
*/
|
||||
public function getAllTables()
|
||||
{
|
||||
$tables = array();
|
||||
$this->addCriterionTable($this, $tables);
|
||||
return $tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* method supporting recursion through all criterions to give
|
||||
* us a string array of tables from each criterion
|
||||
* @return void
|
||||
*/
|
||||
private function addCriterionTable(Criterion $c, array &$s)
|
||||
{
|
||||
$s[] = $c->getTable();
|
||||
foreach ( $c->getClauses() as $clause ) {
|
||||
$this->addCriterionTable($clause, $s);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get an array of all criterion attached to this
|
||||
* recursing through all sub criterion
|
||||
* @return array Criterion[]
|
||||
*/
|
||||
public function getAttachedCriterion()
|
||||
{
|
||||
$criterions = array($this);
|
||||
foreach ($this->getClauses() as $criterion) {
|
||||
$criterions = array_merge($criterions, $criterion->getAttachedCriterion());
|
||||
}
|
||||
return $criterions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures deep cloning of attached objects
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
foreach ($this->clauses as $key => $criterion) {
|
||||
$this->clauses[$key] = clone $criterion;
|
||||
}
|
||||
}
|
||||
}
|
54
library/propel/runtime/lib/query/CriterionIterator.php
Normal file
54
library/propel/runtime/lib/query/CriterionIterator.php
Normal file
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class that implements SPL Iterator interface. This allows foreach () to
|
||||
* be used w/ Criteria objects. Probably there is no performance advantage
|
||||
* to doing it this way, but it makes sense -- and simpler code.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.query
|
||||
*/
|
||||
class CriterionIterator implements Iterator
|
||||
{
|
||||
|
||||
private $idx = 0;
|
||||
private $criteria;
|
||||
private $criteriaKeys;
|
||||
private $criteriaSize;
|
||||
|
||||
public function __construct(Criteria $criteria) {
|
||||
$this->criteria = $criteria;
|
||||
$this->criteriaKeys = $criteria->keys();
|
||||
$this->criteriaSize = count($this->criteriaKeys);
|
||||
}
|
||||
|
||||
public function rewind() {
|
||||
$this->idx = 0;
|
||||
}
|
||||
|
||||
public function valid() {
|
||||
return $this->idx < $this->criteriaSize;
|
||||
}
|
||||
|
||||
public function key() {
|
||||
return $this->criteriaKeys[$this->idx];
|
||||
}
|
||||
|
||||
public function current() {
|
||||
return $this->criteria->getCriterion($this->criteriaKeys[$this->idx]);
|
||||
}
|
||||
|
||||
public function next() {
|
||||
$this->idx++;
|
||||
}
|
||||
|
||||
}
|
250
library/propel/runtime/lib/query/Join.php
Normal file
250
library/propel/runtime/lib/query/Join.php
Normal file
|
@ -0,0 +1,250 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Data object to describe a join between two tables, for example
|
||||
* <pre>
|
||||
* table_a LEFT JOIN table_b ON table_a.id = table_b.a_id
|
||||
* </pre>
|
||||
*
|
||||
* @author Francois Zaninotto (Propel)
|
||||
* @author Hans Lellelid <hans@xmpl.org> (Propel)
|
||||
* @author Kaspars Jaudzems <kaspars.jaudzems@inbox.lv> (Propel)
|
||||
* @author Frank Y. Kim <frank.kim@clearink.com> (Torque)
|
||||
* @author John D. McNally <jmcnally@collab.net> (Torque)
|
||||
* @author Brett McLaughlin <bmclaugh@algx.net> (Torque)
|
||||
* @author Eric Dobbs <eric@dobbse.net> (Torque)
|
||||
* @author Henning P. Schmiedehausen <hps@intermeta.de> (Torque)
|
||||
* @author Sam Joseph <sam@neurogrid.com> (Torque)
|
||||
* @package propel.runtime.query
|
||||
*/
|
||||
class Join
|
||||
{
|
||||
// default comparison type
|
||||
const EQUAL = "=";
|
||||
|
||||
// the left parts of the join condition
|
||||
protected $left = array();
|
||||
|
||||
// the right parts of the join condition
|
||||
protected $right = array();
|
||||
|
||||
// the comparison operators for each pair of columns in the join condition
|
||||
protected $operator = array();
|
||||
|
||||
// the type of the join (LEFT JOIN, ...), or null for an implicit join
|
||||
protected $joinType = null;
|
||||
|
||||
// the number of conditions in the join
|
||||
protected $count = 0;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Use it preferably with no arguments, and then use addCondition() and setJoinType()
|
||||
* Syntax with arguments used mainly for backwards compatibility
|
||||
*
|
||||
* @param string $leftColumn The left column of the join condition
|
||||
* (may contain an alias name)
|
||||
* @param string $rightColumn The right column of the join condition
|
||||
* (may contain an alias name)
|
||||
* @param string $joinType The type of the join. Valid join types are null (implicit join),
|
||||
* Criteria::LEFT_JOIN, Criteria::RIGHT_JOIN, and Criteria::INNER_JOIN
|
||||
*/
|
||||
public function __construct($leftColumn = null, $rightColumn = null, $joinType = null)
|
||||
{
|
||||
if(!is_null($leftColumn)) {
|
||||
if (!is_array($leftColumn)) {
|
||||
// simple join
|
||||
$this->addCondition($leftColumn, $rightColumn);
|
||||
} else {
|
||||
// join with multiple conditions
|
||||
if (count($leftColumn) != count($rightColumn) ) {
|
||||
throw new PropelException("Unable to create join because the left column count isn't equal to the right column count");
|
||||
}
|
||||
foreach ($leftColumn as $key => $value)
|
||||
{
|
||||
$this->addCondition($value, $rightColumn[$key]);
|
||||
}
|
||||
}
|
||||
$this->setJoinType($joinType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Join condition definition
|
||||
*
|
||||
* @param string $left The left column of the join condition
|
||||
* (may contain an alias name)
|
||||
* @param string $right The right column of the join condition
|
||||
* (may contain an alias name)
|
||||
* @param string $operator The comparison operator of the join condition, default Join::EQUAL
|
||||
*/
|
||||
public function addCondition($left, $right, $operator = self::EQUAL)
|
||||
{
|
||||
$this->left[] = $left;
|
||||
$this->right[] = $right;
|
||||
$this->operator[] = $operator;
|
||||
$this->count++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the number of conditions in the join
|
||||
*
|
||||
* @return integer The number of conditions in the join
|
||||
*/
|
||||
public function countConditions()
|
||||
{
|
||||
return $this->count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of the join conditions
|
||||
*
|
||||
* @return array An array of arrays representing (left, comparison, right) for each condition
|
||||
*/
|
||||
public function getConditions()
|
||||
{
|
||||
$conditions = array();
|
||||
for ($i=0; $i < $this->count; $i++) {
|
||||
$conditions[] = array(
|
||||
'left' => $this->getLeftColumn($i),
|
||||
'operator' => $this->getOperator($i),
|
||||
'right' => $this->getRightColumn($i)
|
||||
);
|
||||
}
|
||||
return $conditions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the comparison operator for the join condition
|
||||
*/
|
||||
public function getOperator($index = 0)
|
||||
{
|
||||
return $this->operator[$index];
|
||||
}
|
||||
|
||||
public function getOperators()
|
||||
{
|
||||
return $this->operator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the join type
|
||||
*
|
||||
* @param string $joinType The type of the join. Valid join types are
|
||||
* null (adding the join condition to the where clause),
|
||||
* Criteria::LEFT_JOIN(), Criteria::RIGHT_JOIN(), and Criteria::INNER_JOIN()
|
||||
*/
|
||||
public function setJoinType($joinType = null)
|
||||
{
|
||||
$this->joinType = $joinType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the join type
|
||||
*
|
||||
* @return string The type of the join, i.e. Criteria::LEFT_JOIN(), ...,
|
||||
* or null for adding the join condition to the where Clause
|
||||
*/
|
||||
public function getJoinType()
|
||||
{
|
||||
return $this->joinType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the left column of the join condition
|
||||
*/
|
||||
public function getLeftColumn($index = 0)
|
||||
{
|
||||
return $this->left[$index];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return all right columns of the join condition
|
||||
*/
|
||||
public function getLeftColumns()
|
||||
{
|
||||
return $this->left;
|
||||
}
|
||||
|
||||
|
||||
public function getLeftColumnName($index = 0)
|
||||
{
|
||||
return substr($this->left[$index], strrpos($this->left[$index], '.') + 1);
|
||||
}
|
||||
|
||||
public function getLeftTableName($index = 0)
|
||||
{
|
||||
return substr($this->left[$index], 0, strrpos($this->left[$index], '.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the right column of the join condition
|
||||
*/
|
||||
public function getRightColumn($index = 0)
|
||||
{
|
||||
return $this->right[$index];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return all right columns of the join condition
|
||||
*/
|
||||
public function getRightColumns()
|
||||
{
|
||||
return $this->right;
|
||||
}
|
||||
|
||||
public function getRightColumnName($index = 0)
|
||||
{
|
||||
return substr($this->right[$index], strrpos($this->right[$index], '.') + 1);
|
||||
}
|
||||
|
||||
public function getRightTableName($index = 0)
|
||||
{
|
||||
return substr($this->right[$index], 0, strrpos($this->right[$index], '.'));
|
||||
}
|
||||
|
||||
public function equals($join)
|
||||
{
|
||||
return $join !== null
|
||||
&& $join instanceof Join
|
||||
&& $this->joinType == $join->getJoinType()
|
||||
&& $this->getConditions() == $join->getConditions();
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a String representation of the class,
|
||||
* mainly for debugging purposes
|
||||
*
|
||||
* @return string A String representation of the class
|
||||
*/
|
||||
public function toString()
|
||||
{
|
||||
$result = '';
|
||||
if ($this->joinType !== null) {
|
||||
$result .= $this->joinType . ' : ';
|
||||
}
|
||||
foreach ($this->getConditions() as $index => $condition) {
|
||||
$result .= implode($condition);
|
||||
if ($index + 1 < $this->count) {
|
||||
$result .= ' AND ';
|
||||
}
|
||||
}
|
||||
$result .= '(ignoreCase not considered)';
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->toString();
|
||||
}
|
||||
}
|
||||
|
1841
library/propel/runtime/lib/query/ModelCriteria.php
Normal file
1841
library/propel/runtime/lib/query/ModelCriteria.php
Normal file
File diff suppressed because it is too large
Load diff
283
library/propel/runtime/lib/query/ModelCriterion.php
Normal file
283
library/propel/runtime/lib/query/ModelCriterion.php
Normal file
|
@ -0,0 +1,283 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is an "inner" class that describes an object in the criteria.
|
||||
*
|
||||
* @author Francois
|
||||
* @version $Revision: 1630 $
|
||||
* @package propel.runtime.query
|
||||
*/
|
||||
class ModelCriterion extends Criterion
|
||||
{
|
||||
protected $clause = '';
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param Criteria $parent The outer class (this is an "inner" class).
|
||||
* @param ColumnMap $column A Column object to help escaping the value
|
||||
* @param mixed $value
|
||||
* @param string $comparison, among ModelCriteria::MODEL_CLAUSE
|
||||
* @param string $clause A simple pseudo-SQL clause, e.g. 'foo.BAR LIKE ?'
|
||||
*/
|
||||
public function __construct(Criteria $outer, $column, $value = null, $comparison = ModelCriteria::MODEL_CLAUSE, $clause)
|
||||
{
|
||||
$this->value = $value;
|
||||
if ($column instanceof ColumnMap) {
|
||||
$this->column = $column->getName();
|
||||
$this->table = $column->getTable()->getName();
|
||||
} else {
|
||||
$dotPos = strrpos($column,'.');
|
||||
if ($dotPos === false) {
|
||||
// no dot => aliased column
|
||||
$this->table = null;
|
||||
$this->column = $column;
|
||||
} else {
|
||||
$this->table = substr($column, 0, $dotPos);
|
||||
$this->column = substr($column, $dotPos+1, strlen($column));
|
||||
}
|
||||
}
|
||||
$this->comparison = ($comparison === null ? Criteria::EQUAL : $comparison);
|
||||
$this->clause = $clause;
|
||||
$this->init($outer);
|
||||
}
|
||||
|
||||
public function getClause()
|
||||
{
|
||||
return $this->clause;
|
||||
}
|
||||
|
||||
/**
|
||||
* Figure out which MocelCriterion method to use
|
||||
* to build the prepared statement and parameters using to the Criterion comparison
|
||||
* and call it to append the prepared statement and the parameters of the current clause.
|
||||
* For performance reasons, this method tests the cases of parent::dispatchPsHandling()
|
||||
* first, and that is not possible through inheritance ; that's why the parent
|
||||
* code is duplicated here.
|
||||
*
|
||||
* @param string &$sb The string that will receive the Prepared Statement
|
||||
* @param array $params A list to which Prepared Statement parameters will be appended
|
||||
*/
|
||||
protected function dispatchPsHandling(&$sb, array &$params)
|
||||
{
|
||||
switch ($this->comparison) {
|
||||
case Criteria::CUSTOM:
|
||||
// custom expression with no parameter binding
|
||||
$this->appendCustomToPs($sb, $params);
|
||||
break;
|
||||
case Criteria::IN:
|
||||
case Criteria::NOT_IN:
|
||||
// table.column IN (?, ?) or table.column NOT IN (?, ?)
|
||||
$this->appendInToPs($sb, $params);
|
||||
break;
|
||||
case Criteria::LIKE:
|
||||
case Criteria::NOT_LIKE:
|
||||
case Criteria::ILIKE:
|
||||
case Criteria::NOT_ILIKE:
|
||||
// table.column LIKE ? or table.column NOT LIKE ? (or ILIKE for Postgres)
|
||||
$this->appendLikeToPs($sb, $params);
|
||||
break;
|
||||
case ModelCriteria::MODEL_CLAUSE:
|
||||
// regular model clause, e.g. 'book.TITLE = ?'
|
||||
$this->appendModelClauseToPs($sb, $params);
|
||||
break;
|
||||
case ModelCriteria::MODEL_CLAUSE_LIKE:
|
||||
// regular model clause, e.g. 'book.TITLE = ?'
|
||||
$this->appendModelClauseLikeToPs($sb, $params);
|
||||
break;
|
||||
case ModelCriteria::MODEL_CLAUSE_SEVERAL:
|
||||
// Ternary model clause, e.G 'book.ID BETWEEN ? AND ?'
|
||||
$this->appendModelClauseSeveralToPs($sb, $params);
|
||||
break;
|
||||
case ModelCriteria::MODEL_CLAUSE_ARRAY:
|
||||
// IN or NOT IN model clause, e.g. 'book.TITLE NOT IN ?'
|
||||
$this->appendModelClauseArrayToPs($sb, $params);
|
||||
break;
|
||||
default:
|
||||
// table.column = ? or table.column >= ? etc. (traditional expressions, the default)
|
||||
$this->appendBasicToPs($sb, $params);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a Prepared Statement representation of the ModelCriterion onto the buffer
|
||||
* For regular model clauses, e.g. 'book.TITLE = ?'
|
||||
*
|
||||
* @param string &$sb The string that will receive the Prepared Statement
|
||||
* @param array $params A list to which Prepared Statement parameters will be appended
|
||||
*/
|
||||
public function appendModelClauseToPs(&$sb, array &$params)
|
||||
{
|
||||
if ($this->value !== null) {
|
||||
$params[] = array('table' => $this->realtable, 'column' => $this->column, 'value' => $this->value);
|
||||
$sb .= str_replace('?', ':p'.count($params), $this->clause);
|
||||
} else {
|
||||
$sb .= $this->clause;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a Prepared Statement representation of the ModelCriterion onto the buffer
|
||||
* For LIKE model clauses, e.g. 'book.TITLE LIKE ?'
|
||||
* Handles case insensitivity for VARCHAR columns
|
||||
*
|
||||
* @param string &$sb The string that will receive the Prepared Statement
|
||||
* @param array $params A list to which Prepared Statement parameters will be appended
|
||||
*/
|
||||
public function appendModelClauseLikeToPs(&$sb, array &$params)
|
||||
{
|
||||
// LIKE is case insensitive in mySQL and SQLite, but not in PostGres
|
||||
// If the column is case insensitive, use ILIKE / NOT ILIKE instead of LIKE / NOT LIKE
|
||||
if ($this->ignoreStringCase && $this->getDb() instanceof DBPostgres) {
|
||||
$this->clause = preg_replace('/LIKE \?$/i', 'ILIKE ?', $this->clause);
|
||||
}
|
||||
$this->appendModelClauseToPs($sb, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a Prepared Statement representation of the ModelCriterion onto the buffer
|
||||
* For ternary model clauses, e.G 'book.ID BETWEEN ? AND ?'
|
||||
*
|
||||
* @param string &$sb The string that will receive the Prepared Statement
|
||||
* @param array $params A list to which Prepared Statement parameters will be appended
|
||||
*/
|
||||
public function appendModelClauseSeveralToPs(&$sb, array &$params)
|
||||
{
|
||||
$clause = $this->clause;
|
||||
foreach ((array) $this->value as $value) {
|
||||
if ($value === null) {
|
||||
// FIXME we eventually need to translate a BETWEEN to
|
||||
// something like WHERE (col < :p1 OR :p1 IS NULL) AND (col < :p2 OR :p2 IS NULL)
|
||||
// in order to support null values
|
||||
throw new PropelException('Null values are not supported inside BETWEEN clauses');
|
||||
}
|
||||
$params[] = array('table' => $this->realtable, 'column' => $this->column, 'value' => $value);
|
||||
$clause = self::strReplaceOnce('?', ':p'.count($params), $clause);
|
||||
}
|
||||
$sb .= $clause;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a Prepared Statement representation of the ModelCriterion onto the buffer
|
||||
* For IN or NOT IN model clauses, e.g. 'book.TITLE NOT IN ?'
|
||||
*
|
||||
* @param string &$sb The string that will receive the Prepared Statement
|
||||
* @param array $params A list to which Prepared Statement parameters will be appended
|
||||
*/
|
||||
public function appendModelClauseArrayToPs(&$sb, array &$params)
|
||||
{
|
||||
$_bindParams = array(); // the param names used in query building
|
||||
$_idxstart = count($params);
|
||||
$valuesLength = 0;
|
||||
foreach ( (array) $this->value as $value ) {
|
||||
$valuesLength++; // increment this first to correct for wanting bind params to start with :p1
|
||||
$params[] = array('table' => $this->realtable, 'column' => $this->column, 'value' => $value);
|
||||
$_bindParams[] = ':p'.($_idxstart + $valuesLength);
|
||||
}
|
||||
if ($valuesLength !== 0) {
|
||||
$sb .= str_replace('?', '(' . implode(',', $_bindParams) . ')', $this->clause);
|
||||
} else {
|
||||
$sb .= (stripos($this->clause, ' NOT IN ') === false) ? "1<>1" : "1=1";
|
||||
}
|
||||
unset ( $value, $valuesLength );
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks another Criteria to see if they contain
|
||||
* the same attributes and hashtable entries.
|
||||
* @return boolean
|
||||
*/
|
||||
public function equals($obj)
|
||||
{
|
||||
// TODO: optimize me with early outs
|
||||
if ($this === $obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (($obj === null) || !($obj instanceof ModelCriterion)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$crit = $obj;
|
||||
|
||||
$isEquiv = ( ( ($this->table === null && $crit->getTable() === null)
|
||||
|| ( $this->table !== null && $this->table === $crit->getTable() )
|
||||
)
|
||||
&& $this->clause === $crit->getClause()
|
||||
&& $this->column === $crit->getColumn()
|
||||
&& $this->comparison === $crit->getComparison());
|
||||
|
||||
// check chained criterion
|
||||
|
||||
$clausesLength = count($this->clauses);
|
||||
$isEquiv &= (count($crit->getClauses()) == $clausesLength);
|
||||
$critConjunctions = $crit->getConjunctions();
|
||||
$critClauses = $crit->getClauses();
|
||||
for ($i=0; $i < $clausesLength && $isEquiv; $i++) {
|
||||
$isEquiv &= ($this->conjunctions[$i] === $critConjunctions[$i]);
|
||||
$isEquiv &= ($this->clauses[$i] === $critClauses[$i]);
|
||||
}
|
||||
|
||||
if ($isEquiv) {
|
||||
$isEquiv &= $this->value === $crit->getValue();
|
||||
}
|
||||
|
||||
return $isEquiv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash code value for the object.
|
||||
*/
|
||||
public function hashCode()
|
||||
{
|
||||
$h = crc32(serialize($this->value)) ^ crc32($this->comparison) ^ crc32($this->clause);
|
||||
|
||||
if ($this->table !== null) {
|
||||
$h ^= crc32($this->table);
|
||||
}
|
||||
|
||||
if ($this->column !== null) {
|
||||
$h ^= crc32($this->column);
|
||||
}
|
||||
|
||||
foreach ( $this->clauses as $clause ) {
|
||||
// TODO: i KNOW there is a php incompatibility with the following line
|
||||
// but i dont remember what it is, someone care to look it up and
|
||||
// replace it if it doesnt bother us?
|
||||
// $clause->appendPsTo($sb='',$params=array());
|
||||
$sb = '';
|
||||
$params = array();
|
||||
$clause->appendPsTo($sb,$params);
|
||||
$h ^= crc32(serialize(array($sb,$params)));
|
||||
unset ( $sb, $params );
|
||||
}
|
||||
|
||||
return $h;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace only once
|
||||
* taken from http://www.php.net/manual/en/function.str-replace.php
|
||||
*
|
||||
*/
|
||||
protected static function strReplaceOnce($search, $replace, $subject)
|
||||
{
|
||||
$firstChar = strpos($subject, $search);
|
||||
if($firstChar !== false) {
|
||||
$beforeStr = substr($subject,0,$firstChar);
|
||||
$afterStr = substr($subject, $firstChar + strlen($search));
|
||||
return $beforeStr.$replace.$afterStr;
|
||||
} else {
|
||||
return $subject;
|
||||
}
|
||||
}
|
||||
}
|
166
library/propel/runtime/lib/query/ModelJoin.php
Normal file
166
library/propel/runtime/lib/query/ModelJoin.php
Normal file
|
@ -0,0 +1,166 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* A ModelJoin is a Join object tied to a RelationMap object
|
||||
*
|
||||
* @author Francois Zaninotto (Propel)
|
||||
* @package propel.runtime.query
|
||||
*/
|
||||
class ModelJoin extends Join
|
||||
{
|
||||
protected $relationMap;
|
||||
protected $tableMap;
|
||||
protected $leftTableAlias;
|
||||
protected $relationAlias;
|
||||
protected $previousJoin;
|
||||
|
||||
public function setRelationMap(RelationMap $relationMap, $leftTableAlias = null, $relationAlias = null)
|
||||
{
|
||||
$leftCols = $relationMap->getLeftColumns();
|
||||
$rightCols = $relationMap->getRightColumns();
|
||||
$nbColumns = $relationMap->countColumnMappings();
|
||||
for ($i=0; $i < $nbColumns; $i++) {
|
||||
$leftColName = ($leftTableAlias ? $leftTableAlias : $leftCols[$i]->getTableName()) . '.' . $leftCols[$i]->getName();
|
||||
$rightColName = ($relationAlias ? $relationAlias : $rightCols[$i]->getTableName()) . '.' . $rightCols[$i]->getName();
|
||||
$this->addCondition($leftColName, $rightColName, Criteria::EQUAL);
|
||||
}
|
||||
$this->relationMap = $relationMap;
|
||||
$this->leftTableAlias = $leftTableAlias;
|
||||
$this->relationAlias = $relationAlias;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRelationMap()
|
||||
{
|
||||
return $this->relationMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the right tableMap for this join
|
||||
*
|
||||
* @param TableMap $tableMap The table map to use
|
||||
*
|
||||
* @return ModelJoin The current join object, for fluid interface
|
||||
*/
|
||||
public function setTableMap(TableMap $tableMap)
|
||||
{
|
||||
$this->tableMap = $tableMap;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the right tableMap for this join
|
||||
*
|
||||
* @return TableMap The table map
|
||||
*/
|
||||
public function getTableMap()
|
||||
{
|
||||
if (null === $this->tableMap && null !== $this->relationMap)
|
||||
{
|
||||
$this->tableMap = $this->relationMap->getRightTable();
|
||||
}
|
||||
return $this->tableMap;
|
||||
}
|
||||
|
||||
public function setPreviousJoin(ModelJoin $join)
|
||||
{
|
||||
$this->previousJoin = $join;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPreviousJoin()
|
||||
{
|
||||
return $this->previousJoin;
|
||||
}
|
||||
|
||||
public function isPrimary()
|
||||
{
|
||||
return null === $this->previousJoin;
|
||||
}
|
||||
|
||||
public function setLeftTableAlias($leftTableAlias)
|
||||
{
|
||||
$this->leftTableAlias = $leftTableAlias;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getLeftTableAlias()
|
||||
{
|
||||
return $this->leftTableAlias;
|
||||
}
|
||||
|
||||
public function hasLeftTableAlias()
|
||||
{
|
||||
return null !== $this->leftTableAlias;
|
||||
}
|
||||
|
||||
public function setRelationAlias($relationAlias)
|
||||
{
|
||||
$this->relationAlias = $relationAlias;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRelationAlias()
|
||||
{
|
||||
return $this->relationAlias;
|
||||
}
|
||||
|
||||
public function hasRelationAlias()
|
||||
{
|
||||
return null !== $this->relationAlias;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the last related, but already hydrated object up until this join
|
||||
* Starting from $startObject and continuously calling the getters to get
|
||||
* to the base object for the current join.
|
||||
*
|
||||
* This method only works if PreviousJoin has been defined,
|
||||
* which only happens when you provide dotted relations when calling join
|
||||
*
|
||||
* @param Object $startObject the start object all joins originate from and which has already hydrated
|
||||
* @return Object the base Object of this join
|
||||
*/
|
||||
public function getObjectToRelate($startObject)
|
||||
{
|
||||
if($this->isPrimary()) {
|
||||
return $startObject;
|
||||
} else {
|
||||
$previousJoin = $this->getPreviousJoin();
|
||||
$previousObject = $previousJoin->getObjectToRelate($startObject);
|
||||
$method = 'get' . $previousJoin->getRelationMap()->getName();
|
||||
return $previousObject->$method();
|
||||
}
|
||||
}
|
||||
|
||||
public function equals($join)
|
||||
{
|
||||
return parent::equals($join)
|
||||
&& $this->relationMap == $join->getRelationMap()
|
||||
&& $this->previousJoin == $join->getPreviousJoin()
|
||||
&& $this->relationAlias == $join->getRelationAlias();
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return parent::toString()
|
||||
. ' tableMap: ' . ($this->tableMap ? get_class($this->tableMap) : 'null')
|
||||
. ' relationMap: ' . $this->relationMap->getName()
|
||||
. ' previousJoin: ' . ($this->previousJoin ? '(' . $this->previousJoin . ')' : 'null')
|
||||
. ' relationAlias: ' . $this->relationAlias;
|
||||
}
|
||||
}
|
||||
|
33
library/propel/runtime/lib/query/PropelQuery.php
Normal file
33
library/propel/runtime/lib/query/PropelQuery.php
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Factory for model queries
|
||||
*
|
||||
* @author François Zaninotto
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.query
|
||||
*/
|
||||
class PropelQuery
|
||||
{
|
||||
public static function from($queryClassAndAlias)
|
||||
{
|
||||
list($class, $alias) = ModelCriteria::getClassAndAlias($queryClassAndAlias);
|
||||
$queryClass = $class . 'Query';
|
||||
if (!class_exists($queryClass)) {
|
||||
throw new PropelException('Cannot find a query class for ' . $class);
|
||||
}
|
||||
$query = new $queryClass();
|
||||
if ($alias !== null) {
|
||||
$query->setModelAlias($alias);
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
}
|
1099
library/propel/runtime/lib/util/BasePeer.php
Normal file
1099
library/propel/runtime/lib/util/BasePeer.php
Normal file
File diff suppressed because it is too large
Load diff
369
library/propel/runtime/lib/util/NodePeer.php
Normal file
369
library/propel/runtime/lib/util/NodePeer.php
Normal file
|
@ -0,0 +1,369 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is a utility interface for all generated NodePeer classes in the system.
|
||||
*
|
||||
* @author Heltem <heltem@o2php.com> (Propel)
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.util
|
||||
*/
|
||||
interface NodePeer
|
||||
{
|
||||
/**
|
||||
* Creates the supplied node as the root node.
|
||||
*
|
||||
* @param object $node Propel object for model
|
||||
* @return object Inserted propel object for model
|
||||
*/
|
||||
public static function createRoot(NodeObject $node);
|
||||
|
||||
/**
|
||||
* Returns the root node for a given scope id
|
||||
*
|
||||
* @param int $scopeId Scope id to determine which root node to return
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return object Propel object for root node
|
||||
*/
|
||||
public static function retrieveRoot($scopeId = 1, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Inserts $child as first child of destination node $parent
|
||||
*
|
||||
* @param object $child Propel object for child node
|
||||
* @param object $parent Propel object for parent node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return void
|
||||
*/
|
||||
public static function insertAsFirstChildOf(NodeObject $child, NodeObject $parent, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Inserts $child as last child of destination node $parent
|
||||
*
|
||||
* @param object $child Propel object for child node
|
||||
* @param object $parent Propel object for parent node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return void
|
||||
*/
|
||||
public static function insertAsLastChildOf(NodeObject $child, NodeObject $parent, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Inserts $sibling as previous sibling to destination node $node
|
||||
*
|
||||
* @param object $node Propel object for destination node
|
||||
* @param object $sibling Propel object for source node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return void
|
||||
*/
|
||||
public static function insertAsPrevSiblingOf(NodeObject $node, NodeObject $sibling, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Inserts $sibling as next sibling to destination node $node
|
||||
*
|
||||
* @param object $node Propel object for destination node
|
||||
* @param object $sibling Propel object for source node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return void
|
||||
*/
|
||||
public static function insertAsNextSiblingOf(NodeObject $node, NodeObject $sibling, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Inserts $parent as parent of given $node.
|
||||
*
|
||||
* @param object $parent Propel object for given parent node
|
||||
* @param object $node Propel object for given destination node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return void
|
||||
* @throws Exception When trying to insert node as parent of a root node
|
||||
*/
|
||||
public static function insertAsParentOf(NodeObject $parent, NodeObject $node, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Inserts $node as root node
|
||||
*
|
||||
* @param object $node Propel object as root node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return void
|
||||
*/
|
||||
public static function insertRoot(NodeObject $node, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Delete root node
|
||||
*
|
||||
* @param int $scopeId Scope id to determine which root node to delete
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return boolean Deletion status
|
||||
*/
|
||||
public static function deleteRoot($scopeId = 1, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Delete $dest node
|
||||
*
|
||||
* @param object $dest Propel object node to delete
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return boolean Deletion status
|
||||
*/
|
||||
public static function deleteNode(NodeObject $dest, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Moves $child to be first child of $parent
|
||||
*
|
||||
* @param object $parent Propel object for parent node
|
||||
* @param object $child Propel object for child node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return void
|
||||
*/
|
||||
public static function moveToFirstChildOf(NodeObject $parent, NodeObject $child, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Moves $node to be last child of $dest
|
||||
*
|
||||
* @param object $dest Propel object for destination node
|
||||
* @param object $node Propel object for source node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return void
|
||||
*/
|
||||
public static function moveToLastChildOf(NodeObject $dest, NodeObject $node, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Moves $node to be prev sibling to $dest
|
||||
*
|
||||
* @param object $dest Propel object for destination node
|
||||
* @param object $node Propel object for source node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return void
|
||||
*/
|
||||
public static function moveToPrevSiblingOf(NodeObject $dest, NodeObject $node, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Moves $node to be next sibling to $dest
|
||||
*
|
||||
* @param object $dest Propel object for destination node
|
||||
* @param object $node Propel object for source node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return void
|
||||
*/
|
||||
public static function moveToNextSiblingOf(NodeObject $dest, NodeObject $node, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Gets first child for the given node if it exists
|
||||
*
|
||||
* @param object $node Propel object for src node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return mixed Propel object if exists else false
|
||||
*/
|
||||
public static function retrieveFirstChild(NodeObject $node, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Gets last child for the given node if it exists
|
||||
*
|
||||
* @param object $node Propel object for src node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return mixed Propel object if exists else false
|
||||
*/
|
||||
public static function retrieveLastChild(NodeObject $node, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Gets prev sibling for the given node if it exists
|
||||
*
|
||||
* @param object $node Propel object for src node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return mixed Propel object if exists else false
|
||||
*/
|
||||
public static function retrievePrevSibling(NodeObject $node, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Gets next sibling for the given node if it exists
|
||||
*
|
||||
* @param object $node Propel object for src node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return mixed Propel object if exists else false
|
||||
*/
|
||||
public static function retrieveNextSibling(NodeObject $node, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Retrieves the entire tree from root
|
||||
*
|
||||
* @param int $scopeId Scope id to determine which scope tree to return
|
||||
* @param PropelPDO $con Connection to use.
|
||||
*/
|
||||
public static function retrieveTree($scopeId = 1, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Retrieves the entire tree from parent $node
|
||||
*
|
||||
* @param PropelPDO $con Connection to use.
|
||||
*/
|
||||
public static function retrieveBranch(NodeObject $node, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Gets direct children for the node
|
||||
*
|
||||
* @param object $node Propel object for parent node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
*/
|
||||
public static function retrieveChildren(NodeObject $node, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Gets all descendants for the node
|
||||
*
|
||||
* @param object $node Propel object for parent node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
*/
|
||||
public static function retrieveDescendants(NodeObject $node, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Gets all siblings for the node
|
||||
*
|
||||
* @param object $node Propel object for src node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
*/
|
||||
public static function retrieveSiblings(NodeObject $node, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Gets ancestor for the given node if it exists
|
||||
*
|
||||
* @param object $node Propel object for src node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return mixed Propel object if exists else false
|
||||
*/
|
||||
public static function retrieveParent(NodeObject $node, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Gets level for the given node
|
||||
*
|
||||
* @param object $node Propel object for src node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return int Level for the given node
|
||||
*/
|
||||
public static function getLevel(NodeObject $node, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Gets number of direct children for given node
|
||||
*
|
||||
* @param object $node Propel object for src node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return int Level for the given node
|
||||
*/
|
||||
public static function getNumberOfChildren(NodeObject $node, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Gets number of descendants for given node
|
||||
*
|
||||
* @param object $node Propel object for src node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return int Level for the given node
|
||||
*/
|
||||
public static function getNumberOfDescendants(NodeObject $node, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Returns path to a specific node as an array, useful to create breadcrumbs
|
||||
*
|
||||
* @param object $node Propel object of node to create path to
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return array Array in order of heirarchy
|
||||
*/
|
||||
public static function getPath(NodeObject $node, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Tests if node is valid
|
||||
*
|
||||
* @param object $node Propel object for src node
|
||||
* @return bool
|
||||
*/
|
||||
public static function isValid(NodeObject $node = null);
|
||||
|
||||
/**
|
||||
* Tests if node is a root
|
||||
*
|
||||
* @param object $node Propel object for src node
|
||||
* @return bool
|
||||
*/
|
||||
public static function isRoot(NodeObject $node);
|
||||
|
||||
/**
|
||||
* Tests if node is a leaf
|
||||
*
|
||||
* @param object $node Propel object for src node
|
||||
* @return bool
|
||||
*/
|
||||
public static function isLeaf(NodeObject $node);
|
||||
|
||||
/**
|
||||
* Tests if $child is a child of $parent
|
||||
*
|
||||
* @param object $child Propel object for node
|
||||
* @param object $parent Propel object for node
|
||||
* @return bool
|
||||
*/
|
||||
public static function isChildOf(NodeObject $child, NodeObject $parent);
|
||||
|
||||
/**
|
||||
* Tests if $node1 is equal to $node2
|
||||
*
|
||||
* @param object $node1 Propel object for node
|
||||
* @param object $node2 Propel object for node
|
||||
* @return bool
|
||||
*/
|
||||
public static function isEqualTo(NodeObject $node1, NodeObject $node2);
|
||||
|
||||
/**
|
||||
* Tests if $node has an ancestor
|
||||
*
|
||||
* @param object $node Propel object for node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return bool
|
||||
*/
|
||||
public static function hasParent(NodeObject $node, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Tests if $node has prev sibling
|
||||
*
|
||||
* @param object $node Propel object for node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return bool
|
||||
*/
|
||||
public static function hasPrevSibling(NodeObject $node, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Tests if $node has next sibling
|
||||
*
|
||||
* @param object $node Propel object for node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return bool
|
||||
*/
|
||||
public static function hasNextSibling(NodeObject $node, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Tests if $node has children
|
||||
*
|
||||
* @param object $node Propel object for node
|
||||
* @return bool
|
||||
*/
|
||||
public static function hasChildren(NodeObject $node);
|
||||
|
||||
/**
|
||||
* Deletes $node and all of its descendants
|
||||
*
|
||||
* @param object $node Propel object for source node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
*/
|
||||
public static function deleteDescendants(NodeObject $node, PropelPDO $con = null);
|
||||
|
||||
/**
|
||||
* Returns a node given its primary key or the node itself
|
||||
*
|
||||
* @param int/object $node Primary key/instance of required node
|
||||
* @param PropelPDO $con Connection to use.
|
||||
* @return object Propel object for model
|
||||
*/
|
||||
public static function getNode($node, PropelPDO $con = null);
|
||||
|
||||
} // NodePeer
|
113
library/propel/runtime/lib/util/PropelAutoloader.php
Executable file
113
library/propel/runtime/lib/util/PropelAutoloader.php
Executable file
|
@ -0,0 +1,113 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Simple autoloader for Propel generated model classes.
|
||||
* This class implements the singleton pattern.
|
||||
*
|
||||
* @author Prancois Zaninotto
|
||||
* @author Fabien Potencier
|
||||
* @version $Revision: 1773 $
|
||||
* @package propel.util
|
||||
*/
|
||||
class PropelAutoloader
|
||||
{
|
||||
|
||||
static protected $instance = null;
|
||||
|
||||
protected $classes = array();
|
||||
|
||||
/**
|
||||
* Retrieves the singleton instance of this class.
|
||||
*
|
||||
* @return PropelAutoloader A PropelAutoloader instance.
|
||||
*/
|
||||
static public function getInstance()
|
||||
{
|
||||
if (!isset(self::$instance)) {
|
||||
self::$instance = new PropelAutoloader();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register PropelAutoloader in spl autoloader.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
static public function register()
|
||||
{
|
||||
ini_set('unserialize_callback_func', 'spl_autoload_call');
|
||||
|
||||
if (false === spl_autoload_register(array(self::getInstance(), 'autoload'))) {
|
||||
throw new Exception(sprintf('Unable to register %s::autoload as an autoloading method.', get_class(self::getInstance())));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister PropelAutoloader from spl autoloader.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
static public function unregister()
|
||||
{
|
||||
spl_autoload_unregister(array(self::getInstance(), 'autoload'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the path for a list of classes.
|
||||
*
|
||||
* @param array $classMap An associative array $className => $classPath
|
||||
*/
|
||||
public function addClassPaths($classMap)
|
||||
{
|
||||
$this->classes = array_merge($this->classes, $classMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the path for a particular class.
|
||||
*
|
||||
* @param string $class A PHP class name
|
||||
* @param string $path A path (absolute or relative to the include path)
|
||||
*/
|
||||
public function addClassPath($class, $path)
|
||||
{
|
||||
$this->classes[$class] = $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path where a particular class can be found.
|
||||
*
|
||||
* @param string $class A PHP class name
|
||||
*
|
||||
* @return string|null A path (absolute or relative to the include path)
|
||||
*/
|
||||
public function getClassPath($class)
|
||||
{
|
||||
return isset($this->classes[$class]) ? $this->classes[$class] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles autoloading of classes that have been registered in this instance
|
||||
*
|
||||
* @param string $class A class name.
|
||||
*
|
||||
* @return boolean Returns true if the class has been loaded
|
||||
*/
|
||||
public function autoload($class)
|
||||
{
|
||||
if (isset($this->classes[$class])) {
|
||||
require $this->classes[$class];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
88
library/propel/runtime/lib/util/PropelColumnTypes.php
Normal file
88
library/propel/runtime/lib/util/PropelColumnTypes.php
Normal file
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Enumeration of Propel types.
|
||||
*
|
||||
* THIS CLASS MUST BE KEPT UP-TO-DATE WITH THE MORE EXTENSIVE GENERATOR VERSION OF THIS CLASS.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org> (Propel)
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.util
|
||||
*/
|
||||
class PropelColumnTypes
|
||||
{
|
||||
|
||||
const
|
||||
CHAR = "CHAR",
|
||||
VARCHAR = "VARCHAR",
|
||||
LONGVARCHAR = "LONGVARCHAR",
|
||||
CLOB = "CLOB",
|
||||
CLOB_EMU = "CLOB_EMU",
|
||||
NUMERIC = "NUMERIC",
|
||||
DECIMAL = "DECIMAL",
|
||||
TINYINT = "TINYINT",
|
||||
SMALLINT = "SMALLINT",
|
||||
INTEGER = "INTEGER",
|
||||
BIGINT = "BIGINT",
|
||||
REAL = "REAL",
|
||||
FLOAT = "FLOAT",
|
||||
DOUBLE = "DOUBLE",
|
||||
BINARY = "BINARY",
|
||||
VARBINARY = "VARBINARY",
|
||||
LONGVARBINARY = "LONGVARBINARY",
|
||||
BLOB = "BLOB",
|
||||
DATE = "DATE",
|
||||
TIME = "TIME",
|
||||
TIMESTAMP = "TIMESTAMP",
|
||||
BU_DATE = "BU_DATE",
|
||||
BU_TIMESTAMP = "BU_TIMESTAMP",
|
||||
BOOLEAN = "BOOLEAN",
|
||||
BOOLEAN_EMU = "BOOLEAN_EMU";
|
||||
|
||||
private static $propelToPdoMap = array(
|
||||
self::CHAR => PDO::PARAM_STR,
|
||||
self::VARCHAR => PDO::PARAM_STR,
|
||||
self::LONGVARCHAR => PDO::PARAM_STR,
|
||||
self::CLOB => PDO::PARAM_LOB,
|
||||
self::CLOB_EMU => PDO::PARAM_STR,
|
||||
self::NUMERIC => PDO::PARAM_STR,
|
||||
self::DECIMAL => PDO::PARAM_STR,
|
||||
self::TINYINT => PDO::PARAM_INT,
|
||||
self::SMALLINT => PDO::PARAM_INT,
|
||||
self::INTEGER => PDO::PARAM_INT,
|
||||
self::BIGINT => PDO::PARAM_STR,
|
||||
self::REAL => PDO::PARAM_STR,
|
||||
self::FLOAT => PDO::PARAM_STR,
|
||||
self::DOUBLE => PDO::PARAM_STR,
|
||||
self::BINARY => PDO::PARAM_STR,
|
||||
self::VARBINARY => PDO::PARAM_STR,
|
||||
self::LONGVARBINARY => PDO::PARAM_STR,
|
||||
self::BLOB => PDO::PARAM_LOB,
|
||||
self::DATE => PDO::PARAM_STR,
|
||||
self::TIME => PDO::PARAM_STR,
|
||||
self::TIMESTAMP => PDO::PARAM_STR,
|
||||
self::BU_DATE => PDO::PARAM_STR,
|
||||
self::BU_TIMESTAMP => PDO::PARAM_STR,
|
||||
self::BOOLEAN => PDO::PARAM_BOOL,
|
||||
self::BOOLEAN_EMU => PDO::PARAM_INT,
|
||||
);
|
||||
|
||||
/**
|
||||
* Resturns the PDO type (PDO::PARAM_* constant) value for the Propel type provided.
|
||||
* @param string $propelType
|
||||
* @return int
|
||||
*/
|
||||
public static function getPdoType($propelType)
|
||||
{
|
||||
return self::$propelToPdoMap[$propelType];
|
||||
}
|
||||
|
||||
}
|
71
library/propel/runtime/lib/util/PropelConditionalProxy.php
Normal file
71
library/propel/runtime/lib/util/PropelConditionalProxy.php
Normal file
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Proxy for conditional statements in a fluid interface.
|
||||
* This class replaces another class for wrong statements,
|
||||
* and silently catches all calls to non-conditional method calls
|
||||
*
|
||||
* @example
|
||||
* <code>
|
||||
* $c->_if(true) // returns $c
|
||||
* ->doStuff() // executed
|
||||
* ->_else() // returns a PropelConditionalProxy instance
|
||||
* ->doOtherStuff() // not executed
|
||||
* ->_endif(); // returns $c
|
||||
* $c->_if(false) // returns a PropelConditionalProxy instance
|
||||
* ->doStuff() // not executed
|
||||
* ->_else() // returns $c
|
||||
* ->doOtherStuff() // executed
|
||||
* ->_endif(); // returns $c
|
||||
* @see Criteria
|
||||
*
|
||||
* @author Francois Zaninotto
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.util
|
||||
*/
|
||||
class PropelConditionalProxy
|
||||
{
|
||||
protected $mainObject;
|
||||
|
||||
public function __construct($mainObject)
|
||||
{
|
||||
$this->mainObject = $mainObject;
|
||||
}
|
||||
|
||||
public function _if()
|
||||
{
|
||||
throw new PropelException('_if() statements cannot be nested');
|
||||
}
|
||||
|
||||
public function _elseif($cond)
|
||||
{
|
||||
if($cond) {
|
||||
return $this->mainObject;
|
||||
} else {
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
public function _else()
|
||||
{
|
||||
return $this->mainObject;
|
||||
}
|
||||
|
||||
public function _endif()
|
||||
{
|
||||
return $this->mainObject;
|
||||
}
|
||||
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
}
|
76
library/propel/runtime/lib/util/PropelDateTime.php
Normal file
76
library/propel/runtime/lib/util/PropelDateTime.php
Normal file
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* DateTime subclass which supports serialization.
|
||||
*
|
||||
* Currently Propel is not using this for storing date/time objects
|
||||
* within model objeects; however, we are keeping it in the repository
|
||||
* because it is useful if you want to store a DateTime object in a session.
|
||||
*
|
||||
* @author Alan Pinstein
|
||||
* @author Soenke Ruempler
|
||||
* @author Hans Lellelid
|
||||
* @package propel.runtime.util
|
||||
*/
|
||||
class PropelDateTime extends DateTime
|
||||
{
|
||||
|
||||
/**
|
||||
* A string representation of the date, for serialization.
|
||||
* @var string
|
||||
*/
|
||||
private $dateString;
|
||||
|
||||
/**
|
||||
* A string representation of the time zone, for serialization.
|
||||
* @var string
|
||||
*/
|
||||
private $tzString;
|
||||
|
||||
/**
|
||||
* Convenience method to enable a more fluent API.
|
||||
* @param string $date Date/time value.
|
||||
* @param DateTimeZone $tz (optional) timezone
|
||||
*/
|
||||
public static function newInstance($date, DateTimeZone $tz = null)
|
||||
{
|
||||
if ($tz) {
|
||||
return new DateTime($date, $tz);
|
||||
} else {
|
||||
return new DateTime($date);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP "magic" function called when object is serialized.
|
||||
* Sets an internal property with the date string and returns properties
|
||||
* of class that should be serialized.
|
||||
* @return array string[]
|
||||
*/
|
||||
function __sleep()
|
||||
{
|
||||
// We need to use a string without a time zone, due to
|
||||
// PHP bug: http://bugs.php.net/bug.php?id=40743
|
||||
$this->dateString = $this->format('Y-m-d H:i:s');
|
||||
$this->tzString = $this->getTimeZone()->getName();
|
||||
return array('dateString', 'tzString');
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP "magic" function called when object is restored from serialized state.
|
||||
* Calls DateTime constructor with previously stored string value of date.
|
||||
*/
|
||||
function __wakeup()
|
||||
{
|
||||
parent::__construct($this->dateString, new DateTimeZone($this->tzString));
|
||||
}
|
||||
|
||||
}
|
349
library/propel/runtime/lib/util/PropelModelPager.php
Normal file
349
library/propel/runtime/lib/util/PropelModelPager.php
Normal file
|
@ -0,0 +1,349 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements a pager based on a ModelCriteria
|
||||
* The code from this class heavily borrows from symfony's sfPager class
|
||||
*
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @author François Zaninotto
|
||||
* @version $Revision: 1665 $
|
||||
* @package propel.runtime.query
|
||||
*/
|
||||
class PropelModelPager implements IteratorAggregate, Countable
|
||||
{
|
||||
protected
|
||||
$query = null,
|
||||
$page = 1,
|
||||
$maxPerPage = 10,
|
||||
$lastPage = 1,
|
||||
$nbResults = 0,
|
||||
$objects = null,
|
||||
$parameters = array(),
|
||||
$currentMaxLink = 1,
|
||||
$parameterHolder = null,
|
||||
$maxRecordLimit = false,
|
||||
$results = null,
|
||||
$resultsCounter = 0;
|
||||
|
||||
public function __construct(Criteria $query, $maxPerPage = 10)
|
||||
{
|
||||
$this->setQuery($query);
|
||||
$this->setMaxPerPage($maxPerPage);
|
||||
}
|
||||
|
||||
public function setQuery(Criteria $query)
|
||||
{
|
||||
$this->query = $query;
|
||||
}
|
||||
|
||||
public function getQuery()
|
||||
{
|
||||
return $this->query;
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
$hasMaxRecordLimit = ($this->getMaxRecordLimit() !== false);
|
||||
$maxRecordLimit = $this->getMaxRecordLimit();
|
||||
|
||||
$qForCount = clone $this->getQuery();
|
||||
$count = $qForCount
|
||||
->offset(0)
|
||||
->limit(0)
|
||||
->count();
|
||||
|
||||
$this->setNbResults($hasMaxRecordLimit ? min($count, $maxRecordLimit) : $count);
|
||||
|
||||
$q = $this->getQuery()
|
||||
->offset(0)
|
||||
->limit(0);
|
||||
|
||||
if (($this->getPage() == 0 || $this->getMaxPerPage() == 0)) {
|
||||
$this->setLastPage(0);
|
||||
} else {
|
||||
$this->setLastPage(ceil($this->getNbResults() / $this->getMaxPerPage()));
|
||||
|
||||
$offset = ($this->getPage() - 1) * $this->getMaxPerPage();
|
||||
$q->offset($offset);
|
||||
|
||||
if ($hasMaxRecordLimit) {
|
||||
$maxRecordLimit = $maxRecordLimit - $offset;
|
||||
if ($maxRecordLimit > $this->getMaxPerPage()) {
|
||||
$q->limit($this->getMaxPerPage());
|
||||
} else {
|
||||
$q->limit($maxRecordLimit);
|
||||
}
|
||||
} else {
|
||||
$q->limit($this->getMaxPerPage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the collection of results in the page
|
||||
*
|
||||
* @return PropelObjectCollection A collection of results
|
||||
*/
|
||||
public function getResults()
|
||||
{
|
||||
if (null === $this->results) {
|
||||
$this->results = $this->getQuery()
|
||||
->setFormatter(ModelCriteria::FORMAT_OBJECT)
|
||||
->find();
|
||||
}
|
||||
return $this->results;
|
||||
}
|
||||
|
||||
public function getCurrentMaxLink()
|
||||
{
|
||||
return $this->currentMaxLink;
|
||||
}
|
||||
|
||||
public function getMaxRecordLimit()
|
||||
{
|
||||
return $this->maxRecordLimit;
|
||||
}
|
||||
|
||||
public function setMaxRecordLimit($limit)
|
||||
{
|
||||
$this->maxRecordLimit = $limit;
|
||||
}
|
||||
|
||||
public function getLinks($nb_links = 5)
|
||||
{
|
||||
$links = array();
|
||||
$tmp = $this->page - floor($nb_links / 2);
|
||||
$check = $this->lastPage - $nb_links + 1;
|
||||
$limit = ($check > 0) ? $check : 1;
|
||||
$begin = ($tmp > 0) ? (($tmp > $limit) ? $limit : $tmp) : 1;
|
||||
|
||||
$i = (int) $begin;
|
||||
while (($i < $begin + $nb_links) && ($i <= $this->lastPage)) {
|
||||
$links[] = $i++;
|
||||
}
|
||||
|
||||
$this->currentMaxLink = count($links) ? $links[count($links) - 1] : 1;
|
||||
|
||||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether the number of results exceeds the max number of results per page
|
||||
*
|
||||
* @return boolean true if the pager displays only a subset of the results
|
||||
*/
|
||||
public function haveToPaginate()
|
||||
{
|
||||
return (($this->getMaxPerPage() != 0) && ($this->getNbResults() > $this->getMaxPerPage()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index of the first element in the page
|
||||
* Returns 1 on the first page, $maxPerPage +1 on the second page, etc
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getFirstIndex()
|
||||
{
|
||||
if ($this->page == 0) {
|
||||
return 1;
|
||||
} else {
|
||||
return ($this->page - 1) * $this->maxPerPage + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index of the last element in the page
|
||||
* Always less than or eaqual to $maxPerPage
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getLastIndex()
|
||||
{
|
||||
if ($this->page == 0) {
|
||||
return $this->nbResults;
|
||||
} else {
|
||||
if (($this->page * $this->maxPerPage) >= $this->nbResults) {
|
||||
return $this->nbResults;
|
||||
} else {
|
||||
return ($this->page * $this->maxPerPage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the total number of results of the query
|
||||
* This can be greater than $maxPerPage
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNbResults()
|
||||
{
|
||||
return $this->nbResults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the total number of results of the query
|
||||
*
|
||||
* @param int $nb
|
||||
*/
|
||||
protected function setNbResults($nb)
|
||||
{
|
||||
$this->nbResults = $nb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the current page is the first page
|
||||
*
|
||||
* @return boolean true if the current page is the first page
|
||||
*/
|
||||
public function isFirstPage()
|
||||
{
|
||||
return $this->getPage() == $this->getFirstPage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of the first page
|
||||
*
|
||||
* @return int Always 1
|
||||
*/
|
||||
public function getFirstPage()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the current page is the last page
|
||||
*
|
||||
* @return boolean true if the current page is the last page
|
||||
*/
|
||||
public function isLastPage()
|
||||
{
|
||||
return $this->getPage() == $this->getLastPage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of the last page
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getLastPage()
|
||||
{
|
||||
return $this->lastPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of the first page
|
||||
*
|
||||
* @param int $page
|
||||
*/
|
||||
protected function setLastPage($page)
|
||||
{
|
||||
$this->lastPage = $page;
|
||||
if ($this->getPage() > $page) {
|
||||
$this->setPage($page);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of the current page
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getPage()
|
||||
{
|
||||
return $this->page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of the current page
|
||||
*
|
||||
* @param int $page
|
||||
*/
|
||||
public function setPage($page)
|
||||
{
|
||||
$this->page = intval($page);
|
||||
if ($this->page <= 0) {
|
||||
// set first page, which depends on a maximum set
|
||||
$this->page = $this->getMaxPerPage() ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of the next page
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNextPage()
|
||||
{
|
||||
return min($this->getPage() + 1, $this->getLastPage());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of the previous page
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getPreviousPage()
|
||||
{
|
||||
return max($this->getPage() - 1, $this->getFirstPage());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum number results per page
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getMaxPerPage()
|
||||
{
|
||||
return $this->maxPerPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum number results per page
|
||||
*
|
||||
* @param int $max
|
||||
*/
|
||||
public function setMaxPerPage($max)
|
||||
{
|
||||
if ($max > 0) {
|
||||
$this->maxPerPage = $max;
|
||||
if ($this->page == 0) {
|
||||
$this->page = 1;
|
||||
}
|
||||
} else if ($max == 0) {
|
||||
$this->maxPerPage = 0;
|
||||
$this->page = 0;
|
||||
} else {
|
||||
$this->maxPerPage = 1;
|
||||
if ($this->page == 0) {
|
||||
$this->page = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getIterator()
|
||||
{
|
||||
return $this->getResults()->getIterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total number of results.
|
||||
*
|
||||
* @see Countable
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return $this->getNbResults();
|
||||
}
|
||||
|
||||
}
|
597
library/propel/runtime/lib/util/PropelPager.php
Normal file
597
library/propel/runtime/lib/util/PropelPager.php
Normal file
|
@ -0,0 +1,597 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* PropelPager
|
||||
*
|
||||
* Example Usage:
|
||||
*
|
||||
* require_once 'propel/util/PropelPager.php';
|
||||
* require_once 'PEACH/Propel/Poem/poemPeer.php';
|
||||
*
|
||||
* $c = new Criteria();
|
||||
* $c->addDescendingOrderByColumn(poemPeer::SID);
|
||||
*
|
||||
* // with join
|
||||
* $pager = new PropelPager($c, 'poemPeer', 'doSelectJoinPoemUsers', 1, 50);
|
||||
*
|
||||
* // without Join
|
||||
*
|
||||
* $pager = new PropelPager($c, 'poemPeer', 'doSelect', 1, 50);
|
||||
*
|
||||
* Some template:
|
||||
*
|
||||
* <p>
|
||||
* Total Pages: <?=$pager->getTotalPages()?> Total Records: <?=$pager->getTotalRecordCount()?>
|
||||
* </p>
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td>
|
||||
* <?if ($link = $pager->getFirstPage):?>
|
||||
* <a href="somescript?page=<?=$link?>"><?=$link?></a>|
|
||||
* <?endif?>
|
||||
* </td>
|
||||
* <td>
|
||||
* <?if ($link = $pager->getPrev()):?>
|
||||
* <a href="somescript?page=<?=$link?>">Previous</a>|
|
||||
* <?endif?>
|
||||
* </td>
|
||||
* <td>
|
||||
* <?foreach ($pager->getPrevLinks() as $link):?>
|
||||
* <a href="somescript?page=<?=$link?>"><?=$link?></a>|
|
||||
* <?endforeach?>
|
||||
* </td>
|
||||
* <td><?=$pager->getPage()?></td>
|
||||
* <td>
|
||||
* <?foreach ($pager->getNextLinks() as $link):?>
|
||||
* | <a href="somescript?page=<?=$link?>"><?=$link?></a>
|
||||
* <?endforeach?>
|
||||
* </td>
|
||||
* <td>
|
||||
* <?if ($link = $pager->getNext()):?>
|
||||
* <a href="somescript?page=<?=$link?>">Last</a>|
|
||||
* <?endif?>
|
||||
* </td>
|
||||
* <td>
|
||||
* <?if ($link = $pager->getLastPage()):?>
|
||||
* <a href="somescript?page=<?=$link?>"><?=$link?></a>|
|
||||
* <?endif?>
|
||||
* </td>
|
||||
* </tr>
|
||||
* </table>
|
||||
* <table id="latestPoems">
|
||||
* <tr>
|
||||
* <th>Title</th>
|
||||
* <th>Auteur</th>
|
||||
* <th>Date</th>
|
||||
* <th>comments</th>
|
||||
* </tr>
|
||||
* <?foreach ($pager->getResult() as $poem):?>
|
||||
* <tr>
|
||||
* <td><?=$poem->getTitle()?></td>
|
||||
* <td><?=$poem->getPoemUsers()->getUname()?></td>
|
||||
* <td><?=$poem->getTime()?></td>
|
||||
* <td><?=$poem->getComments()?></td>
|
||||
* </tr>
|
||||
* <?endforeach?>
|
||||
* </table>
|
||||
*
|
||||
*
|
||||
* @author Rob Halff <info@rhalff.com>
|
||||
* @author Niklas Närhinen <niklas@narhinen.net>
|
||||
* @version $Revision: 1612 $
|
||||
* @copyright Copyright (c) 2004 Rob Halff: LGPL - See LICENCE
|
||||
* @package propel.runtime.util
|
||||
*/
|
||||
class PropelPager implements Countable, Iterator
|
||||
{
|
||||
|
||||
private $recordCount;
|
||||
private $pages;
|
||||
private $peerClass;
|
||||
private $peerSelectMethod;
|
||||
private $peerCountMethod;
|
||||
private $criteria;
|
||||
private $countCriteria;
|
||||
private $page;
|
||||
private $rs = null;
|
||||
|
||||
//Iterator vars
|
||||
private $currentKey = 0;
|
||||
|
||||
/** @var int Start row (offset) */
|
||||
protected $start = 0;
|
||||
|
||||
/** @var int Max rows to return (0 means all) */
|
||||
protected $max = 0;
|
||||
|
||||
/**
|
||||
* Create a new Propel Pager.
|
||||
* @param Criteria $c
|
||||
* @param string $peerClass The name of the static Peer class.
|
||||
* @param string $peerSelectMethod The name of the static method for selecting content from the Peer class.
|
||||
* @param int $page The current page (1-based).
|
||||
* @param int $rowsPerPage The number of rows that should be displayed per page.
|
||||
*/
|
||||
public function __construct($c = null, $peerClass = null, $peerSelectMethod = null, $page = 1, $rowsPerPage = 25)
|
||||
{
|
||||
if (!isset($c)) {
|
||||
$c = new Criteria();
|
||||
}
|
||||
$this->setCriteria($c);
|
||||
$this->setPeerClass($peerClass);
|
||||
$this->setPeerSelectMethod($peerSelectMethod);
|
||||
$this->guessPeerCountMethod();
|
||||
$this->setPage($page);
|
||||
$this->setRowsPerPage($rowsPerPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the criteria for this pager.
|
||||
* @param Criteria $c
|
||||
* @return void
|
||||
*/
|
||||
public function setCriteria(Criteria $c)
|
||||
{
|
||||
$this->criteria = $c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Criteria object for this pager.
|
||||
* @return Criteria
|
||||
*/
|
||||
public function getCriteria()
|
||||
{
|
||||
return $this->criteria;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Peer Classname
|
||||
*
|
||||
* @param string $class
|
||||
* @return void
|
||||
*/
|
||||
public function setPeerClass($class)
|
||||
{
|
||||
$this->peerClass = $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Peer Classname.
|
||||
* @return string
|
||||
*/
|
||||
public function getPeerClass()
|
||||
{
|
||||
return $this->peerClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Peer select method.
|
||||
* This exists for legacy support, please use setPeerSelectMethod().
|
||||
* @param string $method The name of the static method to call on the Peer class.
|
||||
* @return void
|
||||
* @see setPeerSelectMethod()
|
||||
* @deprecated
|
||||
*/
|
||||
public function setPeerMethod($method)
|
||||
{
|
||||
$this->setPeerSelectMethod($method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Peer select method.
|
||||
* This exists for legacy support, please use getPeerSelectMethod().
|
||||
* @return string
|
||||
* @see getPeerSelectMethod()
|
||||
* @deprecated
|
||||
*/
|
||||
public function getPeerMethod()
|
||||
{
|
||||
return $this->getPeerSelectMethod();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Peer select method.
|
||||
*
|
||||
* @param string $method The name of the static method to call on the Peer class.
|
||||
* @return void
|
||||
*/
|
||||
public function setPeerSelectMethod($method)
|
||||
{
|
||||
$this->peerSelectMethod = $method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Peer select method.
|
||||
* @return string
|
||||
*/
|
||||
public function getPeerSelectMethod()
|
||||
{
|
||||
return $this->peerSelectMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Count method.
|
||||
* This is set based on the Peer method, for example if Peer method is doSelectJoin*() then the
|
||||
* count method will be doCountJoin*().
|
||||
* @param string $method The name of the static method to call on the Peer class.
|
||||
*/
|
||||
public function setPeerCountMethod($method)
|
||||
{
|
||||
$this->peerCountMethod = $method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Peer count method.
|
||||
*/
|
||||
public function getPeerCountMethod()
|
||||
{
|
||||
return $this->peerCountMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Guesses the Peer count method based on the select method.
|
||||
*/
|
||||
private function guessPeerCountMethod()
|
||||
{
|
||||
$selectMethod = $this->getPeerSelectMethod();
|
||||
if ($selectMethod == 'doSelect') {
|
||||
$countMethod = 'doCount';
|
||||
} elseif ( ($pos = stripos($selectMethod, 'doSelectJoin')) === 0) {
|
||||
$countMethod = 'doCount' . substr($selectMethod, strlen('doSelect'));
|
||||
} else {
|
||||
// we will fall back to doCount() if we don't understand the join
|
||||
// method; however, it probably won't be accurate. Maybe triggering an error would
|
||||
// be appropriate ...
|
||||
$countMethod = 'doCount';
|
||||
}
|
||||
$this->setPeerCountMethod($countMethod);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the paged resultset
|
||||
*
|
||||
* @return mixed $rs
|
||||
*/
|
||||
public function getResult()
|
||||
{
|
||||
if (!isset($this->rs)) {
|
||||
$this->doRs();
|
||||
}
|
||||
|
||||
return $this->rs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the paged resultset
|
||||
*
|
||||
* Main method which creates a paged result set based on the criteria
|
||||
* and the requested peer select method.
|
||||
*
|
||||
*/
|
||||
private function doRs()
|
||||
{
|
||||
$this->criteria->setOffset($this->start);
|
||||
$this->criteria->setLimit($this->max);
|
||||
$this->rs = call_user_func(array($this->getPeerClass(), $this->getPeerSelectMethod()), $this->criteria);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first page
|
||||
*
|
||||
* For now I can only think of returning 1 always.
|
||||
* It should probably return 0 if there are no pages
|
||||
*
|
||||
* @return int 1
|
||||
*/
|
||||
public function getFirstPage()
|
||||
{
|
||||
return '1';
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to indicate whether current page is the first page.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function atFirstPage()
|
||||
{
|
||||
return $this->getPage() == $this->getFirstPage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last page
|
||||
*
|
||||
* @return int $lastPage
|
||||
*/
|
||||
public function getLastPage()
|
||||
{
|
||||
$totalPages = $this->getTotalPages();
|
||||
if ($totalPages == 0) {
|
||||
return 1;
|
||||
} else {
|
||||
return $totalPages;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to indicate whether current page is the last page.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function atLastPage()
|
||||
{
|
||||
return $this->getPage() == $this->getLastPage();
|
||||
}
|
||||
|
||||
/**
|
||||
* get total pages
|
||||
*
|
||||
* @return int $this->pages
|
||||
*/
|
||||
public function getTotalPages() {
|
||||
if (!isset($this->pages)) {
|
||||
$recordCount = $this->getTotalRecordCount();
|
||||
if ($this->max > 0) {
|
||||
$this->pages = ceil($recordCount/$this->max);
|
||||
} else {
|
||||
$this->pages = 0;
|
||||
}
|
||||
}
|
||||
return $this->pages;
|
||||
}
|
||||
|
||||
/**
|
||||
* get an array of previous id's
|
||||
*
|
||||
* @param int $range
|
||||
* @return array $links
|
||||
*/
|
||||
public function getPrevLinks($range = 5)
|
||||
{
|
||||
$total = $this->getTotalPages();
|
||||
$start = $this->getPage() - 1;
|
||||
$end = $this->getPage() - $range;
|
||||
$first = $this->getFirstPage();
|
||||
$links = array();
|
||||
for ($i=$start; $i>$end; $i--) {
|
||||
if ($i < $first) {
|
||||
break;
|
||||
}
|
||||
$links[] = $i;
|
||||
}
|
||||
|
||||
return array_reverse($links);
|
||||
}
|
||||
|
||||
/**
|
||||
* get an array of next id's
|
||||
*
|
||||
* @param int $range
|
||||
* @return array $links
|
||||
*/
|
||||
public function getNextLinks($range = 5)
|
||||
{
|
||||
$total = $this->getTotalPages();
|
||||
$start = $this->getPage() + 1;
|
||||
$end = $this->getPage() + $range;
|
||||
$last = $this->getLastPage();
|
||||
$links = array();
|
||||
for ($i=$start; $i<$end; $i++) {
|
||||
if ($i > $last) {
|
||||
break;
|
||||
}
|
||||
$links[] = $i;
|
||||
}
|
||||
|
||||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether last page is complete
|
||||
*
|
||||
* @return bool Last page complete or not
|
||||
*/
|
||||
public function isLastPageComplete()
|
||||
{
|
||||
return !($this->getTotalRecordCount() % $this->max);
|
||||
}
|
||||
|
||||
/**
|
||||
* get previous id
|
||||
*
|
||||
* @return mixed $prev
|
||||
*/
|
||||
public function getPrev() {
|
||||
if ($this->getPage() != $this->getFirstPage()) {
|
||||
$prev = $this->getPage() - 1;
|
||||
} else {
|
||||
$prev = false;
|
||||
}
|
||||
return $prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* get next id
|
||||
*
|
||||
* @return mixed $next
|
||||
*/
|
||||
public function getNext() {
|
||||
if ($this->getPage() != $this->getLastPage()) {
|
||||
$next = $this->getPage() + 1;
|
||||
} else {
|
||||
$next = false;
|
||||
}
|
||||
return $next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current page number (First page is 1).
|
||||
* @param int $page
|
||||
* @return void
|
||||
*/
|
||||
public function setPage($page)
|
||||
{
|
||||
$this->page = $page;
|
||||
// (re-)calculate start rec
|
||||
$this->calculateStart();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current page.
|
||||
* @return int
|
||||
*/
|
||||
public function getPage()
|
||||
{
|
||||
return $this->page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of rows per page.
|
||||
* @param int $r
|
||||
*/
|
||||
public function setRowsPerPage($r)
|
||||
{
|
||||
$this->max = $r;
|
||||
// (re-)calculate start rec
|
||||
$this->calculateStart();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of rows per page.
|
||||
* @return int
|
||||
*/
|
||||
public function getRowsPerPage()
|
||||
{
|
||||
return $this->max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate startrow / max rows based on current page and rows-per-page.
|
||||
* @return void
|
||||
*/
|
||||
private function calculateStart()
|
||||
{
|
||||
$this->start = ( ($this->page - 1) * $this->max );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the total number of (un-LIMITed) records.
|
||||
*
|
||||
* This method will perform a query that executes un-LIMITed query.
|
||||
*
|
||||
* @return int Total number of records - disregarding page, maxrows, etc.
|
||||
*/
|
||||
public function getTotalRecordCount()
|
||||
{
|
||||
|
||||
if (!isset($this->rs)) {
|
||||
$this->doRs();
|
||||
}
|
||||
|
||||
if (empty($this->recordCount)) {
|
||||
$this->countCriteria = clone $this->criteria;
|
||||
$this->countCriteria->setLimit(0);
|
||||
$this->countCriteria->setOffset(0);
|
||||
|
||||
$this->recordCount = call_user_func(
|
||||
array(
|
||||
$this->getPeerClass(),
|
||||
$this->getPeerCountMethod()
|
||||
),
|
||||
$this->countCriteria
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
return $this->recordCount;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the start row or offset.
|
||||
* @param int $v
|
||||
*/
|
||||
public function setStart($v)
|
||||
{
|
||||
$this->start = $v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets max rows (limit).
|
||||
* @param int $v
|
||||
* @return void
|
||||
*/
|
||||
public function setMax($v)
|
||||
{
|
||||
$this->max = $v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the count of the current page's records
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->getResult());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current element of the iterator
|
||||
* @return mixed
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
if (!isset($this->rs)) {
|
||||
$this->doRs();
|
||||
}
|
||||
return $this->rs[$this->currentKey];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current key of the iterator
|
||||
* @return int
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return $this->currentKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Advances the iterator to the next element
|
||||
* @return void
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
$this->currentKey++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the iterator to the first element
|
||||
* @return void
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
$this->currentKey = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current key exists in the container
|
||||
* @return boolean
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
if (!isset($this->rs)) {
|
||||
$this->doRs();
|
||||
}
|
||||
return in_array($this->currentKey, array_keys($this->rs));
|
||||
}
|
||||
|
||||
}
|
35
library/propel/runtime/lib/validator/BasicValidator.php
Normal file
35
library/propel/runtime/lib/validator/BasicValidator.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Basic Validator interface.
|
||||
*
|
||||
* BasicValidator objects perform validation without any knowledge of column/table
|
||||
* context. They are simply given an input and some value and asked whether the input
|
||||
* is valid.
|
||||
*
|
||||
* @author Michael Aichler <aichler@mediacluster.de>
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.validator
|
||||
*/
|
||||
interface BasicValidator
|
||||
{
|
||||
|
||||
/**
|
||||
* Determine whether a value meets the criteria specified
|
||||
*
|
||||
* @param ValidatorMap $map A column map object for the column to be validated.
|
||||
* @param string $str a <code>String</code> to be tested
|
||||
*
|
||||
* @return mixed TRUE if valid, error message otherwise
|
||||
*/
|
||||
public function isValid(ValidatorMap $map, $str);
|
||||
|
||||
}
|
68
library/propel/runtime/lib/validator/MatchValidator.php
Normal file
68
library/propel/runtime/lib/validator/MatchValidator.php
Normal file
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* A validator for regular expressions.
|
||||
*
|
||||
* This validator will return true, when the passed value *matches* the
|
||||
* regular expression.
|
||||
*
|
||||
* ## This class replaces the former class MaskValidator ##
|
||||
*
|
||||
* If you do want to test if the value does *not* match an expression,
|
||||
* you can use the MatchValidator class instead.
|
||||
*
|
||||
* Below is an example usage for your Propel xml schema file.
|
||||
*
|
||||
* <code>
|
||||
* <column name="email" type="VARCHAR" size="128" required="true" />
|
||||
* <validator column="username">
|
||||
* <!-- allow strings that match the email adress pattern -->
|
||||
* <rule
|
||||
* name="match"
|
||||
* value="/^([a-zA-Z0-9])+([\.a-zA-Z0-9_-])*@([a-zA-Z0-9])+(\.[a-zA-Z0-9_-]+)+$/"
|
||||
* message="Please enter a valid email address." />
|
||||
* </validator>
|
||||
* </code>
|
||||
*
|
||||
* @author Michael Aichler <aichler@mediacluster.de>
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.validator
|
||||
*/
|
||||
class MatchValidator implements BasicValidator
|
||||
{
|
||||
/**
|
||||
* Prepares the regular expression entered in the XML
|
||||
* for use with preg_match().
|
||||
* @param string $exp
|
||||
* @return string Prepared regular expession.
|
||||
*/
|
||||
private function prepareRegexp($exp)
|
||||
{
|
||||
// remove surrounding '/' marks so that they don't get escaped in next step
|
||||
if ($exp{0} !== '/' || $exp{strlen($exp)-1} !== '/' ) {
|
||||
$exp = '/' . $exp . '/';
|
||||
}
|
||||
|
||||
// if they did not escape / chars; we do that for them
|
||||
$exp = preg_replace('/([^\\\])\/([^$])/', '$1\/$2', $exp);
|
||||
|
||||
return $exp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the passed string matches regular expression.
|
||||
*/
|
||||
public function isValid (ValidatorMap $map, $str)
|
||||
{
|
||||
return (preg_match($this->prepareRegexp($map->getValue()), $str) != 0);
|
||||
}
|
||||
}
|
39
library/propel/runtime/lib/validator/MaxLengthValidator.php
Normal file
39
library/propel/runtime/lib/validator/MaxLengthValidator.php
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* A validator for maximum string length.
|
||||
*
|
||||
* Below is an example usage for your Propel xml schema file.
|
||||
*
|
||||
* Note that if you have specified the size attribute in the column tag
|
||||
* you do not have to specify it as value in the validator rule again as
|
||||
* this is done automatically.
|
||||
*
|
||||
* <code>
|
||||
* <column name="username" type="VARCHAR" size="25" required="true" />
|
||||
*
|
||||
* <validator column="username">
|
||||
* <rule name="maxLength" message="Passwort must be at least ${value} characters !" />
|
||||
* </validator>
|
||||
* </code>
|
||||
*
|
||||
* @author Michael Aichler <aichler@mediacluster.de>
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.validator
|
||||
*/
|
||||
class MaxLengthValidator implements BasicValidator
|
||||
{
|
||||
|
||||
public function isValid (ValidatorMap $map, $str)
|
||||
{
|
||||
return strlen($str) <= intval($map->getValue());
|
||||
}
|
||||
}
|
43
library/propel/runtime/lib/validator/MaxValueValidator.php
Normal file
43
library/propel/runtime/lib/validator/MaxValueValidator.php
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* A validator for maximum values.
|
||||
*
|
||||
* Below is an example usage for your Propel xml schema file.
|
||||
*
|
||||
* <code>
|
||||
* <column name="articles" type="INTEGER" required="true" />
|
||||
*
|
||||
* <validator column="articles">
|
||||
* <rule name="minValue" value="1" message="Minimum value for selected articles is ${value} !" />
|
||||
* <rule name="maxValue" value="10" message="Maximum value for selected articles is ${value} !" />
|
||||
* </validator>
|
||||
* </code>
|
||||
*
|
||||
* @author Michael Aichler <aichler@mediacluster.de>
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.validator
|
||||
*/
|
||||
class MaxValueValidator implements BasicValidator
|
||||
{
|
||||
|
||||
/**
|
||||
* @see BasicValidator::isValid()
|
||||
*/
|
||||
public function isValid (ValidatorMap $map, $value)
|
||||
{
|
||||
if (is_null($value) == false && is_numeric($value) == true) {
|
||||
return intval($value) <= intval($map->getValue());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
36
library/propel/runtime/lib/validator/MinLengthValidator.php
Normal file
36
library/propel/runtime/lib/validator/MinLengthValidator.php
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* A validator for minimum string length.
|
||||
*
|
||||
* <code>
|
||||
* <column name="password" type="VARCHAR" size="34" required="true" />
|
||||
*
|
||||
* <validator column="password">
|
||||
* <rule name="minLength" value="5" message="Passwort must be at least ${value} characters !" />
|
||||
* </validator>
|
||||
* </code>
|
||||
*
|
||||
* @author Michael Aichler <aichler@mediacluster.de>
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.validator
|
||||
*/
|
||||
class MinLengthValidator implements BasicValidator
|
||||
{
|
||||
|
||||
/**
|
||||
* @see BasicValidator::isValid()
|
||||
*/
|
||||
public function isValid (ValidatorMap $map, $str)
|
||||
{
|
||||
return strlen($str) >= intval($map->getValue());
|
||||
}
|
||||
}
|
43
library/propel/runtime/lib/validator/MinValueValidator.php
Normal file
43
library/propel/runtime/lib/validator/MinValueValidator.php
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* A validator for minimum values.
|
||||
*
|
||||
* Below is an example usage for your Propel xml schema file.
|
||||
*
|
||||
* <code>
|
||||
* <column name="articles" type="INTEGER" required="true" />
|
||||
*
|
||||
* <validator column="articles">
|
||||
* <rule name="minValue" value="1" message="Minimum value for selected articles is ${value} !" />
|
||||
* <rule name="maxValue" value="10" message="Maximum value for selected articles is ${value} !" />
|
||||
* </validator>
|
||||
* </code>
|
||||
*
|
||||
* @author Michael Aichler <aichler@mediacluster.de>
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.validator
|
||||
*/
|
||||
class MinValueValidator implements BasicValidator
|
||||
{
|
||||
|
||||
/**
|
||||
* @see BasicValidator::isValid()
|
||||
*/
|
||||
public function isValid (ValidatorMap $map, $value)
|
||||
{
|
||||
if (is_null($value) == false && is_numeric($value)) {
|
||||
return intval($value) >= intval($map->getValue());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
66
library/propel/runtime/lib/validator/NotMatchValidator.php
Normal file
66
library/propel/runtime/lib/validator/NotMatchValidator.php
Normal file
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* A validator for regular expressions.
|
||||
*
|
||||
* This validator will return true, when the passed value does *not* match
|
||||
* the regular expression.
|
||||
*
|
||||
* If you do want to test if the value *matches* an expression, you can use
|
||||
* the MatchValidator class instead.
|
||||
*
|
||||
* Below is an example usage for your Propel xml schema file.
|
||||
*
|
||||
* <code>
|
||||
* <column name="ISBN" type="VARCHAR" size="20" required="true" />
|
||||
* <validator column="username">
|
||||
* <!-- disallow everything that's not a digit or minus -->
|
||||
* <rule
|
||||
* name="notMatch"
|
||||
* value="/[^\d-]+/"
|
||||
* message="Please enter a valid email adress." />
|
||||
* </validator>
|
||||
* </code>
|
||||
*
|
||||
* @author Michael Aichler <aichler@mediacluster.de>
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.validator
|
||||
*/
|
||||
class NotMatchValidator implements BasicValidator
|
||||
{
|
||||
/**
|
||||
* Prepares the regular expression entered in the XML
|
||||
* for use with preg_match().
|
||||
* @param string $exp
|
||||
* @return string Prepared regular expession.
|
||||
*/
|
||||
private function prepareRegexp($exp)
|
||||
{
|
||||
// remove surrounding '/' marks so that they don't get escaped in next step
|
||||
if ($exp{0} !== '/' || $exp{strlen($exp)-1} !== '/' ) {
|
||||
$exp = '/' . $exp . '/';
|
||||
}
|
||||
|
||||
// if they did not escape / chars; we do that for them
|
||||
$exp = preg_replace('/([^\\\])\/([^$])/', '$1\/$2', $exp);
|
||||
|
||||
return $exp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the passed string matches regular expression.
|
||||
*/
|
||||
public function isValid (ValidatorMap $map, $str)
|
||||
{
|
||||
return (preg_match($this->prepareRegexp($map->getValue()), $str) == 0);
|
||||
}
|
||||
}
|
38
library/propel/runtime/lib/validator/RequiredValidator.php
Normal file
38
library/propel/runtime/lib/validator/RequiredValidator.php
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* A validator for required fields.
|
||||
*
|
||||
* Below is an example usage for your Propel xml schema file.
|
||||
*
|
||||
* <code>
|
||||
* <column name="username" type="VARCHAR" size="25" required="true" />
|
||||
*
|
||||
* <validator column="username">
|
||||
* <rule name="required" message="Username is required." />
|
||||
* </validator>
|
||||
* </code>
|
||||
*
|
||||
* @author Michael Aichler <aichler@mediacluster.de>
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.validator
|
||||
*/
|
||||
class RequiredValidator implements BasicValidator
|
||||
{
|
||||
|
||||
/**
|
||||
* @see BasicValidator::isValid()
|
||||
*/
|
||||
public function isValid (ValidatorMap $map, $str)
|
||||
{
|
||||
return ($str !== null && $str !== "");
|
||||
}
|
||||
}
|
68
library/propel/runtime/lib/validator/TypeValidator.php
Normal file
68
library/propel/runtime/lib/validator/TypeValidator.php
Normal file
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* A validator for validating the (PHP) type of the value submitted.
|
||||
*
|
||||
* <code>
|
||||
* <column name="some_int" type="INTEGER" required="true"/>
|
||||
*
|
||||
* <validator column="some_int">
|
||||
* <rule name="type" value="integer" message="Please specify an integer value for some_int column." />
|
||||
* </validator>
|
||||
* </code>
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.validator
|
||||
*/
|
||||
class TypeValidator implements BasicValidator
|
||||
{
|
||||
public function isValid(ValidatorMap $map, $value)
|
||||
{
|
||||
switch ($map->getValue()) {
|
||||
case 'array':
|
||||
return is_array($value);
|
||||
break;
|
||||
case 'bool':
|
||||
case 'boolean':
|
||||
return is_bool($value);
|
||||
break;
|
||||
case 'float':
|
||||
return is_float($value);
|
||||
break;
|
||||
case 'int':
|
||||
case 'integer':
|
||||
return is_int($value);
|
||||
break;
|
||||
case 'numeric':
|
||||
return is_numeric($value);
|
||||
break;
|
||||
case 'object':
|
||||
return is_object($value);
|
||||
break;
|
||||
case 'resource':
|
||||
return is_resource($value);
|
||||
break;
|
||||
case 'scalar':
|
||||
return is_scalar($value);
|
||||
break;
|
||||
case 'string':
|
||||
return is_string($value);
|
||||
break;
|
||||
case 'function':
|
||||
return function_exists($value);
|
||||
break;
|
||||
default:
|
||||
throw new PropelException('Unkonwn type ' . $map->getValue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
48
library/propel/runtime/lib/validator/UniqueValidator.php
Normal file
48
library/propel/runtime/lib/validator/UniqueValidator.php
Normal file
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* A validator for unique column names.
|
||||
*
|
||||
* <code>
|
||||
* <column name="username" type="VARCHAR" size="25" required="true" />
|
||||
*
|
||||
* <validator column="username">
|
||||
* <rule name="unique" message="Username already exists !" />
|
||||
* </validator>
|
||||
* </code>
|
||||
*
|
||||
* @author Michael Aichler <aichler@mediacluster.de>
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.validator
|
||||
*/
|
||||
class UniqueValidator implements BasicValidator
|
||||
{
|
||||
|
||||
/**
|
||||
* @see BasicValidator::isValid()
|
||||
*/
|
||||
public function isValid (ValidatorMap $map, $str)
|
||||
{
|
||||
$column = $map->getColumn();
|
||||
|
||||
$c = new Criteria();
|
||||
$c->add($column->getFullyQualifiedName(), $str, Criteria::EQUAL);
|
||||
|
||||
$table = $column->getTable()->getClassName();
|
||||
|
||||
$clazz = $table . 'Peer';
|
||||
$count = call_user_func(array($clazz, 'doCount'), $c);
|
||||
|
||||
$isValid = ($count === 0);
|
||||
|
||||
return $isValid;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* A validator for valid values (e.g. for enum fields)
|
||||
*
|
||||
* <code>
|
||||
* <column name="address_type" type="VARCHAR" required="true" default="delivery" />
|
||||
*
|
||||
* <validator column="address_type">
|
||||
* <rule name="validValues" value="account|delivery" message="Please select a valid address type." />
|
||||
* </validator>
|
||||
* </code>
|
||||
*
|
||||
* @author Michael Aichler <aichler@mediacluster.de>
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.validator
|
||||
*/
|
||||
class ValidValuesValidator implements BasicValidator
|
||||
{
|
||||
|
||||
public function isValid (ValidatorMap $map, $str)
|
||||
{
|
||||
return in_array($str, preg_split("/[|,]/", $map->getValue()));
|
||||
}
|
||||
}
|
115
library/propel/runtime/lib/validator/ValidationFailed.php
Normal file
115
library/propel/runtime/lib/validator/ValidationFailed.php
Normal file
|
@ -0,0 +1,115 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Propel package.
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Simple class that serves as a container for any information about a failed validation.
|
||||
*
|
||||
* Currently this class stores the qualified column name (e.g. tablename.COLUMN_NAME) and
|
||||
* the message that should be displayed to the user.
|
||||
*
|
||||
* An array of these objects will be returned by BasePeer::doValidate() if validation
|
||||
* failed.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1612 $
|
||||
* @package propel.runtime.validator
|
||||
* @see BasePeer::doValidate()
|
||||
*/
|
||||
class ValidationFailed {
|
||||
|
||||
/** Column name in tablename.COLUMN_NAME format */
|
||||
private $colname;
|
||||
|
||||
/** Message to display to user. */
|
||||
private $message;
|
||||
|
||||
/** Validator object that caused this to fail. */
|
||||
private $validator;
|
||||
|
||||
/**
|
||||
* Construct a new ValidationFailed object.
|
||||
* @param string $colname Column name.
|
||||
* @param string $message Message to display to user.
|
||||
* @param object $validator The Validator that caused this column to fail.
|
||||
*/
|
||||
public function __construct($colname, $message, $validator = null)
|
||||
{
|
||||
$this->colname = $colname;
|
||||
$this->message = $message;
|
||||
$this->validator = $validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the column name.
|
||||
* @param string $v
|
||||
*/
|
||||
public function setColumn($v)
|
||||
{
|
||||
$this->colname = $v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the column name.
|
||||
* @return string Qualified column name (tablename.COLUMN_NAME)
|
||||
*/
|
||||
public function getColumn()
|
||||
{
|
||||
return $this->colname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the message for the validation failure.
|
||||
* @param string $v
|
||||
*/
|
||||
public function setMessage($v)
|
||||
{
|
||||
$this->message = $v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message for the validation failure.
|
||||
* @return string
|
||||
*/
|
||||
public function getMessage()
|
||||
{
|
||||
return $this->message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the validator object that caused this to fail.
|
||||
* @param object $v
|
||||
*/
|
||||
public function setValidator($v)
|
||||
{
|
||||
$this->validator = $v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the validator object that caused this to fail.
|
||||
* @return object
|
||||
*/
|
||||
public function getValidator()
|
||||
{
|
||||
return $this->validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* "magic" method to get string represenation of object.
|
||||
* Maybe someday PHP5 will support the invoking this method automatically
|
||||
* on (string) cast. Until then it's pretty useless.
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getMessage();
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue