initial commit

This commit is contained in:
Chris Sewell
2012-11-28 03:55:08 -05:00
parent 7adb399b2e
commit cf140a2e97
3247 changed files with 492437 additions and 0 deletions

945
lib/symfony/vendor/propel/util/BasePeer.php vendored Executable file
View File

@ -0,0 +1,945 @@
<?php
/*
* $Id: BasePeer.php 536 2007-01-10 14:30:38Z heltem $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://propel.phpdb.org>.
*/
include_once 'propel/adapter/DBAdapter.php';
include_once 'propel/map/ColumnMap.php';
include_once 'propel/map/DatabaseMap.php';
include_once 'propel/map/MapBuilder.php';
include_once 'propel/map/TableMap.php';
include_once 'propel/map/ValidatorMap.php';
include_once 'propel/validator/ValidationFailed.php';
/**
* This is a utility class for all generated Peer classes in the system.
*
* Peer classes are responsible for isolating all of the database access
* for a specific business object. They execute all of the SQL
* against the database. Over time this class has grown to include
* utility methods which ease execution of cross-database queries and
* the implementation of concrete Peers.
*
* @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 Stephen Haberman <stephenh@chase3000.com> (Torque)
* @version $Revision: 536 $
* @package propel.util
*/
class BasePeer
{
/** Array (hash) that contains the cached mapBuilders. */
private static $mapBuilders = array();
/** Array (hash) that contains cached validators */
private static $validatorMap = array();
/**
* phpname type
* e.g. 'AuthorId'
*/
const TYPE_PHPNAME = 'phpName';
/**
* column (peer) name type
* e.g. 'book.AUTHOR_ID'
*/
const TYPE_COLNAME = 'colName';
/**
* column fieldname type
* e.g. 'author_id'
*/
const TYPE_FIELDNAME = 'fieldName';
/**
* num type
* simply the numerical array index, e.g. 4
*/
const TYPE_NUM = 'num';
static public function getFieldnames ($classname, $type = self::TYPE_PHPNAME) {
// TODO we should take care of including the peer class here
$peerclass = 'Base' . $classname . 'Peer'; // TODO is this always true?
$callable = array($peerclass, 'getFieldnames');
$args = array($type);
return call_user_func_array($callable, $args);
}
static public function translateFieldname($classname, $fieldname, $fromType, $toType) {
// TODO we should take care of including the peer class here
$peerclass = 'Base' . $classname . 'Peer'; // TODO is this always true?
$callable = array($peerclass, 'translateFieldname');
$args = array($fieldname, $fromType, $toType);
return call_user_func_array($callable, $args);
}
/**
* Method to perform deletes based on values and keys in a
* Criteria.
*
* @param Criteria $criteria The criteria to use.
* @param Connection $con A Connection.
* @return int The number of rows affected by last statement execution. For most
* uses there is only one delete statement executed, so this number
* will correspond to the number of rows affected by the call to this
* method. Note that the return value does require that this information
* is returned (supported) by the Creole db driver.
* @throws PropelException
*/
public static function doDelete(Criteria $criteria, Connection $con)
{
$db = Propel::getDB($criteria->getDbName());
$dbMap = Propel::getDatabaseMap($criteria->getDbName());
// Set up a list of required tables (one DELETE statement will
// be executed per table)
$tables_keys = array();
foreach($criteria as $c) {
foreach($c->getAllTables() as $tableName) {
$tableName2 = $criteria->getTableForAlias($tableName);
if ($tableName2 !== null) {
$tables_keys[$tableName2 . ' ' . $tableName] = true;
} else {
$tables_keys[$tableName] = true;
}
}
} // foreach criteria->keys()
$affectedRows = 0; // initialize this in case the next loop has no iterations.
$tables = array_keys($tables_keys);
foreach($tables as $tableName) {
$whereClause = array();
$selectParams = array();
foreach($dbMap->getTable($tableName)->getColumns() as $colMap) {
$key = $tableName . '.' . $colMap->getColumnName();
if ($criteria->containsKey($key)) {
$sb = "";
$criteria->getCriterion($key)->appendPsTo($sb, $selectParams);
$whereClause[] = $sb;
}
}
if (empty($whereClause)) {
throw new PropelException("Cowardly refusing to delete from table $tableName with empty WHERE clause.");
}
// Execute the statement.
try {
$sqlSnippet = implode(" AND ", $whereClause);
if ($criteria->isSingleRecord()) {
$sql = "SELECT COUNT(*) FROM " . $tableName . " WHERE " . $sqlSnippet;
$stmt = $con->prepareStatement($sql);
self::populateStmtValues($stmt, $selectParams, $dbMap);
$rs = $stmt->executeQuery(ResultSet::FETCHMODE_NUM);
$rs->next();
if ($rs->getInt(1) > 1) {
$rs->close();
throw new PropelException("Expecting to delete 1 record, but criteria match multiple.");
}
$rs->close();
}
$sql = "DELETE FROM " . $tableName . " WHERE " . $sqlSnippet;
Propel::log($sql, Propel::LOG_DEBUG);
$stmt = $con->prepareStatement($sql);
self::populateStmtValues($stmt, $selectParams, $dbMap);
$affectedRows = $stmt->executeUpdate();
} catch (Exception $e) {
Propel::log($e->getMessage(), Propel::LOG_ERR);
throw new PropelException("Unable to execute DELETE statement.",$e);
}
} // for each table
return $affectedRows;
}
/**
* Method to deletes all contents of specified table.
*
* This method is invoked from generated Peer classes like this:
* <code>
* public static function doDeleteAll($con = null)
* {
* if ($con === null) $con = Propel::getConnection(self::DATABASE_NAME);
* BasePeer::doDeleteAll(self::TABLE_NAME, $con);
* }
* </code>
*
* @param string $tableName The name of the table to empty.
* @param Connection $con A Connection.
* @return int The number of rows affected by the statement. Note
* that the return value does require that this information
* is returned (supported) by the Creole db driver.
* @throws PropelException - wrapping SQLException caught from statement execution.
*/
public static function doDeleteAll($tableName, Connection $con)
{
try {
$sql = "DELETE FROM " . $tableName;
Propel::log($sql, Propel::LOG_DEBUG);
$stmt = $con->prepareStatement($sql);
return $stmt->executeUpdate();
} catch (Exception $e) {
Propel::log($e->getMessage(), Propel::LOG_ERR);
throw new PropelException("Unable to perform DELETE ALL operation.", $e);
}
}
/**
* Method to perform inserts based on values and keys in a
* Criteria.
* <p>
* If the primary key is auto incremented the data in Criteria
* will be inserted and the auto increment value will be returned.
* <p>
* If the primary key is included in Criteria then that value will
* be used to insert the row.
* <p>
* If no primary key is included in Criteria then we will try to
* figure out the primary key from the database map and insert the
* row with the next available id using util.db.IDBroker.
* <p>
* If no primary key is defined for the table the values will be
* inserted as specified in Criteria and null will be returned.
*
* @param Criteria $criteria Object containing values to insert.
* @param Connection $con A Connection.
* @return mixed The primary key for the new row if (and only if!) the primary key
* is auto-generated. Otherwise will return <code>null</code>.
* @throws PropelException
*/
public static function doInsert(Criteria $criteria, Connection $con) {
// the primary key
$id = null;
// Get the table name and method for determining the primary
// key value.
$keys = $criteria->keys();
if (!empty($keys)) {
$tableName = $criteria->getTableName( $keys[0] );
} else {
throw new PropelException("Database insert attempted without anything specified to insert");
}
$dbMap = Propel::getDatabaseMap($criteria->getDbName());
$tableMap = $dbMap->getTable($tableName);
$keyInfo = $tableMap->getPrimaryKeyMethodInfo();
$useIdGen = $tableMap->isUseIdGenerator();
$keyGen = $con->getIdGenerator();
$pk = self::getPrimaryKey($criteria);
// only get a new key value if you need to
// the reason is that a primary key might be defined
// but you are still going to set its value. for example:
// a join table where both keys are primary and you are
// setting both columns with your own values
// pk will be null if there is no primary key defined for the table
// we're inserting into.
if ($pk !== null && $useIdGen && !$criteria->containsKey($pk->getFullyQualifiedName())) {
// If the keyMethod is SEQUENCE get the id before the insert.
if ($keyGen->isBeforeInsert()) {
try {
$id = $keyGen->getId($keyInfo);
} catch (Exception $e) {
throw new PropelException("Unable to get sequence id.", $e);
}
$criteria->add($pk->getFullyQualifiedName(), $id);
}
}
try {
$qualifiedCols = $criteria->keys(); // we need table.column cols when populating values
$columns = array(); // but just 'column' cols for the SQL
foreach($qualifiedCols as $qualifiedCol) {
$columns[] = substr($qualifiedCol, strpos($qualifiedCol, '.') + 1);
}
$sql = "INSERT INTO " . $tableName
. " (" . implode(",", $columns) . ")"
. " VALUES (" . substr(str_repeat("?,", count($columns)), 0, -1) . ")";
Propel::log($sql, Propel::LOG_DEBUG);
$stmt = $con->prepareStatement($sql);
self::populateStmtValues($stmt, self::buildParams($qualifiedCols, $criteria), $dbMap);
$stmt->executeUpdate();
} catch (Exception $e) {
Propel::log($e->getMessage(), Propel::LOG_ERR);
throw new PropelException("Unable to execute INSERT statement.", $e);
}
// If the primary key column is auto-incremented, get the id
// now.
if ($pk !== null && $useIdGen && $keyGen->isAfterInsert()) {
try {
$id = $keyGen->getId($keyInfo);
} catch (Exception $e) {
throw new PropelException("Unable to get autoincrement id.", $e);
}
}
return $id;
}
/**
* Method used to update rows in the DB. Rows are selected based
* on selectCriteria and updated using values in updateValues.
* <p>
* Use this method for performing an update of the kind:
* <p>
* WHERE some_column = some value AND could_have_another_column =
* another value AND so on.
*
* @param $selectCriteria A Criteria object containing values used in where
* clause.
* @param $updateValues A Criteria object containing values used in set
* clause.
* @param $con The Connection to use.
* @return int The number of rows affected by last update statement. For most
* uses there is only one update statement executed, so this number
* will correspond to the number of rows affected by the call to this
* method. Note that the return value does require that this information
* is returned (supported) by the Creole db driver.
* @throws PropelException
*/
public static function doUpdate(Criteria $selectCriteria, Criteria $updateValues, Connection $con) {
$db = Propel::getDB($selectCriteria->getDbName());
$dbMap = Propel::getDatabaseMap($selectCriteria->getDbName());
// Get list of required tables, containing all columns
$tablesColumns = $selectCriteria->getTablesColumns();
// we also need the columns for the update SQL
$updateTablesColumns = $updateValues->getTablesColumns();
$affectedRows = 0; // initialize this in case the next loop has no iterations.
foreach($tablesColumns as $tableName => $columns) {
$whereClause = array();
$selectParams = array();
foreach($columns as $colName) {
$sb = "";
$selectCriteria->getCriterion($colName)->appendPsTo($sb, $selectParams);
$whereClause[] = $sb;
}
$rs = null;
$stmt = null;
try {
$sqlSnippet = implode(" AND ", $whereClause);
if ($selectCriteria->isSingleRecord()) {
// Get affected records.
$sql = "SELECT COUNT(*) FROM " . $tableName . " WHERE " . $sqlSnippet;
$stmt = $con->prepareStatement($sql);
self::populateStmtValues($stmt, $selectParams, $dbMap);
$rs = $stmt->executeQuery(ResultSet::FETCHMODE_NUM);
$rs->next();
if ($rs->getInt(1) > 1) {
$rs->close();
throw new PropelException("Expected to update 1 record, multiple matched.");
}
$rs->close();
}
$sql = "UPDATE " . $tableName . " SET ";
foreach($updateTablesColumns[$tableName] as $col) {
$sql .= substr($col, strpos($col, '.') + 1) . " = ?,";
}
$sql = substr($sql, 0, -1) . " WHERE " . $sqlSnippet;
Propel::log($sql, Propel::LOG_DEBUG);
$stmt = $con->prepareStatement($sql);
// Replace '?' with the actual values
self::populateStmtValues($stmt, array_merge(self::buildParams($updateTablesColumns[$tableName], $updateValues), $selectParams), $dbMap);
$affectedRows = $stmt->executeUpdate();
$stmt->close();
} catch (Exception $e) {
if ($rs) $rs->close();
if ($stmt) $stmt->close();
Propel::log($e->getMessage(), Propel::LOG_ERR);
throw new PropelException("Unable to execute UPDATE statement.", $e);
}
} // foreach table in the criteria
return $affectedRows;
}
/**
* Executes query build by createSelectSql() and returns ResultSet.
*
* @param Criteria $criteria A Criteria.
* @param Connection $con A connection to use.
* @return ResultSet The resultset.
* @throws PropelException
* @see createSelectSql()
*/
public static function doSelect(Criteria $criteria, $con = null)
{
$dbMap = Propel::getDatabaseMap($criteria->getDbName());
if ($con === null)
$con = Propel::getConnection($criteria->getDbName());
$stmt = null;
try {
// Transaction support exists for (only?) Postgres, which must
// have SELECT statements that include bytea columns wrapped w/
// transactions.
if ($criteria->isUseTransaction()) $con->begin();
$params = array();
$sql = self::createSelectSql($criteria, $params);
$stmt = $con->prepareStatement($sql);
$stmt->setLimit($criteria->getLimit());
$stmt->setOffset($criteria->getOffset());
self::populateStmtValues($stmt, $params, $dbMap);
$rs = $stmt->executeQuery(ResultSet::FETCHMODE_NUM);
if ($criteria->isUseTransaction()) $con->commit();
} catch (Exception $e) {
if ($stmt) $stmt->close();
if ($criteria->isUseTransaction()) $con->rollback();
Propel::log($e->getMessage(), Propel::LOG_ERR);
throw new PropelException($e);
}
return $rs;
}
/**
* Applies any validators that were defined in the schema to the specified columns.
*
* @param string $dbName The name of the database
* @param string $tableName The name of the table
* @param array $columns Array of column names as key and column values as value.
*/
public static function doValidate($dbName, $tableName, $columns)
{
$dbMap = Propel::getDatabaseMap($dbName);
$tableMap = $dbMap->getTable($tableName);
$failureMap = array(); // map of ValidationFailed objects
foreach($columns as $colName => $colValue) {
if ($tableMap->containsColumn($colName)) {
$col = $tableMap->getColumn($colName);
foreach($col->getValidators() as $validatorMap) {
$validator = BasePeer::getValidator($validatorMap->getClass());
if($validator && ($col->isNotNull() || $colValue !== null) && $validator->isValid($validatorMap, $colValue) === false) {
if (!isset($failureMap[$colName])) { // for now we do one ValidationFailed per column, not per rule
$failureMap[$colName] = new ValidationFailed($colName, $validatorMap->getMessage(), $validator);
}
}
}
}
}
return (!empty($failureMap) ? $failureMap : true);
}
/**
* Helper method which returns the primary key contained
* in the given Criteria object.
*
* @param Criteria $criteria A Criteria.
* @return ColumnMap If the Criteria object contains a primary
* key, or null if it doesn't.
* @throws PropelException
*/
private static function getPrimaryKey(Criteria $criteria)
{
// Assume all the keys are for the same table.
$keys = $criteria->keys();
$key = $keys[0];
$table = $criteria->getTableName($key);
$pk = null;
if (!empty($table)) {
$dbMap = Propel::getDatabaseMap($criteria->getDbName());
if ($dbMap === null) {
throw new PropelException("\$dbMap is null");
}
if ($dbMap->getTable($table) === null) {
throw new PropelException("\$dbMap->getTable() is null");
}
$columns = $dbMap->getTable($table)->getColumns();
foreach(array_keys($columns) as $key) {
if ($columns[$key]->isPrimaryKey()) {
$pk = $columns[$key];
break;
}
}
}
return $pk;
}
/**
* Method to create an SQL query based on values in a Criteria.
*
* This method creates only prepared statement SQL (using ? where values
* will go). The second parameter ($params) stores the values that need
* to be set before the statement is executed. The reason we do it this way
* is to let the Creole layer handle all escaping & value formatting.
*
* @param Criteria $criteria Criteria for the SELECT query.
* @param array &$params Parameters that are to be replaced in prepared statement.
* @return string
* @throws PropelException Trouble creating the query string.
*/
public static function createSelectSql(Criteria $criteria, &$params) {
$db = Propel::getDB($criteria->getDbName());
$dbMap = Propel::getDatabaseMap($criteria->getDbName());
// redundant definition $selectModifiers = array();
$selectClause = array();
$fromClause = array();
$joinClause = array();
$joinTables = array();
$whereClause = array();
$orderByClause = array();
// redundant definition $groupByClause = array();
$orderBy = $criteria->getOrderByColumns();
$groupBy = $criteria->getGroupByColumns();
$ignoreCase = $criteria->isIgnoreCase();
$select = $criteria->getSelectColumns();
$aliases = $criteria->getAsColumns();
// simple copy
$selectModifiers = $criteria->getSelectModifiers();
// get selected columns
foreach($select as $columnName) {
// expect every column to be of "table.column" formation
// it could be a function: e.g. MAX(books.price)
$tableName = null;
$selectClause[] = $columnName; // the full column name: e.g. MAX(books.price)
$parenPos = strpos($columnName, '(');
$dotPos = strpos($columnName, '.');
// [HL] I think we really only want to worry about adding stuff to
// the fromClause if this function has a TABLE.COLUMN in it at all.
// e.g. COUNT(*) should not need this treatment -- or there needs to
// be special treatment for '*'
if ($dotPos !== false) {
if ($parenPos === false) { // table.column
$tableName = substr($columnName, 0, $dotPos);
} else { // FUNC(table.column)
$tableName = substr($columnName, $parenPos + 1, $dotPos - ($parenPos + 1));
// functions may contain qualifiers so only take the last
// word as the table name.
// COUNT(DISTINCT books.price)
$lastSpace = strpos($tableName, ' ');
if ($lastSpace !== false) { // COUNT(DISTINCT books.price)
$tableName = substr($tableName, $lastSpace + 1);
}
}
$tableName2 = $criteria->getTableForAlias($tableName);
if ($tableName2 !== null) {
$fromClause[] = $tableName2 . ' ' . $tableName;
} else {
$fromClause[] = $tableName;
}
} // if $dotPost !== null
}
// set the aliases
foreach($aliases as $alias => $col) {
$selectClause[] = $col . " AS " . $alias;
}
// add the criteria to WHERE clause
// this will also add the table names to the FROM clause if they are not already
// invluded via a LEFT JOIN
foreach($criteria->keys() as $key) {
$criterion = $criteria->getCriterion($key);
$someCriteria = $criterion->getAttachedCriterion();
$someCriteriaLength = count($someCriteria);
$table = null;
for ($i=0; $i < $someCriteriaLength; $i++) {
$tableName = $someCriteria[$i]->getTable();
$table = $criteria->getTableForAlias($tableName);
if ($table !== null) {
$fromClause[] = $table . ' ' . $tableName;
} else {
$fromClause[] = $tableName;
$table = $tableName;
}
$ignoreCase =
(($criteria->isIgnoreCase()
|| $someCriteria[$i]->isIgnoreCase())
&& ($dbMap->getTable($table)->getColumn($someCriteria[$i]->getColumn())->getType() == "string" )
);
$someCriteria[$i]->setIgnoreCase($ignoreCase);
}
$criterion->setDB($db);
$sb = "";
$criterion->appendPsTo($sb, $params);
$whereClause[] = $sb;
}
// handle RIGHT (straight) joins
// Loop through the joins,
// joins with a null join type will be added to the FROM clause and the condition added to the WHERE clause.
// joins of a specified type: the LEFT side will be added to the fromClause and the RIGHT to the joinClause
// New Code.
foreach ((array) $criteria->getJoins() as $join) { // we'll only loop if there's actually something here
// The join might have been established using an alias name
$leftTable = $join->getLeftTableName();
$leftTableAlias = '';
if ($realTable = $criteria->getTableForAlias($leftTable)) {
$leftTableAlias = " $leftTable";
$leftTable = $realTable;
}
$rightTable = $join->getRightTableName();
$rightTableAlias = '';
if ($realTable = $criteria->getTableForAlias($rightTable)) {
$rightTableAlias = " $rightTable";
$rightTable = $realTable;
}
// determine if casing is relevant.
if ($ignoreCase = $criteria->isIgnoreCase()) {
$leftColType = $dbMap->getTable($leftTable)->getColumn($join->getLeftColumnName())->getType();
$rightColType = $dbMap->getTable($rightTable)->getColumn($join->getRightColumnName())->getType();
$ignoreCase = ($leftColType == 'string' || $rightColType == 'string');
}
// build the condition
if ($ignoreCase) {
$condition = $db->ignoreCase($join->getLeftColumn()) . '=' . $db->ignoreCase($join->getRightColumn());
} else {
$condition = $join->getLeftColumn() . '=' . $join->getRightColumn();
}
// add 'em to the queues..
if ($joinType = $join->getJoinType()) {
if (!$fromClause) {
$fromClause[] = $leftTable . $leftTableAlias;
}
$joinTables[] = $rightTable . $rightTableAlias;
$joinClause[] = $join->getJoinType() . ' ' . $rightTable . $rightTableAlias . " ON ($condition)";
} else {
$fromClause[] = $leftTable . $leftTableAlias;
$fromClause[] = $rightTable . $rightTableAlias;
$whereClause[] = $condition;
}
}
// Unique from clause elements
$fromClause = array_unique($fromClause);
// tables should not exist in both the from and join clauses
if ($joinTables && $fromClause) {
foreach ($fromClause as $fi => $ftable) {
if (in_array($ftable, $joinTables)) {
unset($fromClause[$fi]);
}
}
}
/*
// Old Code.
$joins =& $criteria->getJoins();
if (!empty($joins)) {
for ($i=0, $joinSize=count($joins); $i < $joinSize; $i++) {
$join =& $joins[$i];
$join1 = $join->getLeftColumn();
$join2 = $join->getRightColumn();
$tableName = substr($join1, 0, strpos($join1, '.'));
$table = $criteria->getTableForAlias($tableName);
if ($table !== null) {
$fromClause[] = $table . ' ' . $tableName;
} else {
$fromClause[] = $tableName;
}
$dot = strpos($join2, '.');
$tableName = substr($join2, 0, $dot);
$table = $criteria->getTableForAlias($tableName);
if ($table !== null) {
$fromClause[] = $table . ' ' . $tableName;
} else {
$fromClause[] = $tableName;
$table = $tableName;
}
$ignoreCase = ($criteria->isIgnoreCase() && ($dbMap->getTable($table)->getColumn(substr($join2, $dot + 1))->getType() == "string"));
if ($ignoreCase) {
$whereClause[] = $db->ignoreCase($join1) . '=' . $db->ignoreCase($join2);
} else {
$whereClause[] = $join1 . '=' . $join2;
}
if ($join->getJoinType()) {
$leftTable = $fromClause[count($fromClause) - 2];
$rightTable = $fromClause[count($fromClause) - 1];
$onClause = $whereClause[count($whereClause) - 1];
unset($whereClause[count($whereClause) - 1]);
$fromClause [] = $leftTable . ' ' . $join->getJoinType() . ' ' . $rightTable . ' ON ' . $onClause;
// remove all references to joinTables made by selectColumns, criteriaColumns
for ($i = 0, $fromClauseSize=count($fromClause); $i < $fromClauseSize; $i++) {
if ($fromClause[$i] == $leftTable || $fromClause[$i] == $rightTable) {
unset($fromClause[$i]);
}
}
} // If join type
} // Join for loop
} // If Joins
*/
// Add the GROUP BY columns
$groupByClause = $groupBy;
$having = $criteria->getHaving();
$havingString = null;
if ($having !== null) {
$sb = "";
$having->appendPsTo($sb, $params);
$havingString = $sb;
}
if (!empty($orderBy)) {
foreach($orderBy as $orderByColumn) {
// Add function expression as-is.
if (strpos($orderByColumn, '(') !== false) {
$orderByClause[] = $orderByColumn;
continue;
}
// Split orderByColumn (i.e. "table.column DESC")
$dotPos = strpos($orderByColumn, '.');
if ($dotPos !== false) {
$tableName = substr($orderByColumn, 0, $dotPos);
$columnName = substr($orderByColumn, $dotPos+1);
}
else {
$tableName = '';
$columnName = $orderByColumn;
}
$spacePos = strpos($columnName, ' ');
if ($spacePos !== false) {
$direction = substr($columnName, $spacePos);
$columnName = substr($columnName, 0, $spacePos);
}
else {
$direction = '';
}
$tableAlias = $tableName;
if ($aliasTableName = $criteria->getTableForAlias($tableName)) {
$tableName = $aliasTableName;
}
$columnAlias = $columnName;
if ($asColumnName = $criteria->getColumnForAs($columnName)) {
$columnName = $asColumnName;
}
$column = $tableName ? $dbMap->getTable($tableName)->getColumn($columnName) : null;
if ($column && $column->getType() == 'string') {
$orderByClause[] = $db->ignoreCaseInOrderBy("$tableAlias.$columnAlias") . $direction;
$selectClause[] = $db->ignoreCaseInOrderBy("$tableAlias.$columnAlias");
}
else {
$orderByClause[] = $orderByColumn;
}
}
}
// Build the SQL from the arrays we compiled
$sql = "SELECT "
.($selectModifiers ? implode(" ", $selectModifiers) . " " : "")
.implode(", ", $selectClause)
." FROM ". ( (!empty($joinClause) && count($fromClause) > 1 && (substr(get_class($db), 0, 7) == 'DBMySQL')) ? "(" . implode(", ", $fromClause) . ")" : implode(", ", $fromClause) )
.($joinClause ? ' ' . implode(' ', $joinClause) : '')
.($whereClause ? " WHERE ".implode(" AND ", $whereClause) : "")
.($groupByClause ? " GROUP BY ".implode(",", $groupByClause) : "")
.($havingString ? " HAVING ".$havingString : "")
.($orderByClause ? " ORDER BY ".implode(",", $orderByClause) : "");
Propel::log($sql . ' [LIMIT: ' . $criteria->getLimit() . ', OFFSET: ' . $criteria->getOffset() . ']', Propel::LOG_DEBUG);
return $sql;
}
/**
* Builds a params array, like the kind populated by Criterion::appendPsTo().
* This is useful for building an array even when it is not using the appendPsTo() method.
* @param array $columns
* @param Criteria $values
* @return array params array('column' => ..., 'table' => ..., 'value' => ...)
*/
private static function buildParams($columns, Criteria $values) {
$params = array();
foreach($columns as $key) {
if ($values->containsKey($key)) {
$crit = $values->getCriterion($key);
$params[] = array('column' => $crit->getColumn(), 'table' => $crit->getTable(), 'value' => $crit->getValue());
}
}
return $params;
}
/**
* Populates values in a prepared statement.
*
* @param PreparedStatement $stmt
* @param array $params array('column' => ..., 'table' => ..., 'value' => ...)
* @param DatabaseMap $dbMap
* @return int The number of params replaced.
*/
private static function populateStmtValues($stmt, $params, DatabaseMap $dbMap)
{
$i = 1;
foreach($params as $param) {
$tableName = $param['table'];
$columnName = $param['column'];
$value = $param['value'];
if ($value === null) {
$stmt->setNull($i++);
} else {
$cMap = $dbMap->getTable($tableName)->getColumn($columnName);
$setter = 'set' . CreoleTypes::getAffix($cMap->getCreoleType());
$stmt->$setter($i++, $value);
}
} // foreach
}
/**
* This function searches for the given validator $name under propel/validator/$name.php,
* imports and caches it.
*
* @param string $classname The dot-path name of class (e.g. myapp.propel.MyValidator)
* @return Validator object or null if not able to instantiate validator class (and error will be logged in this case)
*/
public static function getValidator($classname)
{
try {
$v = isset(self::$validatorMap[$classname]) ? self::$validatorMap[$classname] : null;
if ($v === null) {
$cls = Propel::import($classname);
$v = new $cls();
self::$validatorMap[$classname] = $v;
}
return $v;
} catch (Exception $e) {
Propel::log("BasePeer::getValidator(): failed trying to instantiate " . $classname . ": ".$e->getMessage(), Propel::LOG_ERR);
}
}
/**
* This method returns the MapBuilder specified in the name
* parameter. You should pass in the full dot-path path to the class, ie:
* myapp.propel.MyMapMapBuilder. The MapBuilder instances are cached in
* this class for speed.
*
* @param string $classname The dot-path name of class (e.g. myapp.propel.MyMapBuilder)
* @return MapBuilder or null (and logs the error) if the MapBuilder was not found.
* @todo -cBasePeer Consider adding app-level caching support for map builders.
*/
public static function getMapBuilder($classname)
{
try {
$mb = isset(self::$mapBuilders[$classname]) ? self::$mapBuilders[$classname] : null;
if ($mb === null) {
$cls = Propel::import($classname);
$mb = new $cls();
self::$mapBuilders[$classname] = $mb;
}
if (!$mb->isBuilt()) {
$mb->doBuild();
}
return $mb;
} catch (Exception $e) {
// Have to catch possible exceptions because method is
// used in initialization of Peers. Log the exception and
// return null.
Propel::log("BasePeer::getMapBuilder() failed trying to instantiate " . $classname . ": " . $e->getMessage(), Propel::LOG_ERR);
}
}
}

1730
lib/symfony/vendor/propel/util/Criteria.php vendored Executable file

File diff suppressed because it is too large Load Diff

188
lib/symfony/vendor/propel/util/PeerInfo.php vendored Executable file
View File

@ -0,0 +1,188 @@
<?php
/*
* $Id: PeerInfo.php 536 2007-01-10 14:30:38Z heltem $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://propel.phpdb.org>.
*/
/**
* Peer Helper Class
*
* Handle Dynamic Peer Access. Trying to solve the problems associated
* with looking at constants, calling methods on static Peer Objects
*
* @author David Giffin <david@giffin.org>
* @copyright Copyright (c) 2000-2003 David Giffin : LGPL - See LICENCE
* @package propel.util
*/
class PeerInfo
{
/** Propel Object Peers */
private static $peers = array();
/** Reflection Objects of the Propel Peers */
private static $reflections = array();
/** Table Maps of the Propel Peers */
private static $maps = array();
/**
* Add a Peer to the list of Peers
*
* @param string $peer The Propel Peer to add
*/
private static function addPeer($peer)
{
$peers = array_keys(self::$peers);
if (!in_array($peer, $peers)) {
self::$peers[$peer] = self::loadPeer($peer);
self::$reflections[$peer] = new reflectionClass($peer);
self::$maps[$peer] = null;
}
}
/**
* Get a constant from the Peer Reflector
*
* @param String The name of the constant
* @return String The Constant String
*/
public static function getPeerConstant($peer, $name)
{
self::addPeer($peer);
return self::$reflections[$peer]->getConstant($name);
}
/**
* Get a Peer from the Peer List
*
* @param string $peer The Propel Peer to add
*/
public static function getPeer($peer) {
self::addPeer($peer);
return self::$peers[$peer];
}
/**
* Load a Peer
*
* You may wat to override this method if your Peers
* are not in the include_path.
*
* @param string $peerName the name of the Peer
*/
public static function loadPeer($peerName)
{
$peerFile = $peerName . ".php";
require_once($peerFile);
$peerObject = new $peerName();
return $peerObject;
}
/**
* Get a Column Constant from a Peer
*
* @param string The PhpName or DB_NAME for the constant
* @return string the Column Constant
*/
public static function getColumnConstant($peer, $name)
{
self::addPeer($peer);
$map = self::getPeer($peer)->getPhpNameMap();
foreach ($map as $phpName => $dbName) {
if ($phpName == $name) {
return self::getPeerConstant($peer, $dbName);
} else if ($dbName == $name) {
return self::getPeerConstant($peer, $dbName);
}
}
return null;
}
/**
* Get the Primary Key for this Peer
*
* @param string $peer The name of the Peer
* @return string The name of the Primary Key
*/
public static function getPrimaryKey($peer)
{
self::addPeer($peer);
$tableMap = self::getTableMap($peer);
$columns = $tableMap->getColumns();
foreach ($columns as $columnName => $column) {
if ($column->isPrimaryKey()) {
return $columnName;
}
}
return null;
}
/**
* Get the Table Map for a Peer
*
* @param string $peer The name of the Peer
* @return TableMap The table map for this Peer
*/
public static function getTableMap($peer)
{
self::addPeer($peer);
if (!self::$maps[$peer]) {
$tableName = self::getTableName($peer);
$dbMap = self::getPeer($peer)->getMapBuilder()->getDatabaseMap();
self::$maps[$peer] = $dbMap->getTable($tableName);
}
return self::$maps[$peer];
}
public static function getTableName($peer)
{
self::addPeer($peer);
return self::getPeerConstant($peer, "TABLE_NAME");
}
/**
* Call a Method from the Static Peer Class
*
* @param string $peer The name of the Peer
* @param string $method The name of the method to call
* @param array $params The parameters to pass to the method
* @return mixed What ever the method returns
*/
public static function callMethod($peer, $method, $params = null)
{
if ($params !== null) {
return call_user_func_array(array($peer, $method), $params);
}
return call_user_func(array($peer, $method));
}
}

543
lib/symfony/vendor/propel/util/PropelPager.php vendored Executable file
View File

@ -0,0 +1,543 @@
<?php
/*
* $Id: PropelPager.php 536 2007-01-10 14:30:38Z heltem $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://propel.phpdb.org>.
*/
/**
* 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>
* @version $Revision: 536 $
* @copyright Copyright (c) 2004 Rob Halff: LGPL - See LICENCE
* @package propel.util
*/
class PropelPager {
private $recordCount;
private $pages;
private $peerClass;
private $peerSelectMethod;
private $peerCountMethod;
private $criteria;
private $countCriteria;
private $page;
private $rs = null;
/** @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;
}
}

160
lib/symfony/vendor/propel/util/Transaction.php vendored Executable file
View File

@ -0,0 +1,160 @@
<?php
/*
* $Id: Transaction.php 536 2007-01-10 14:30:38Z heltem $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://propel.phpdb.org>.
*/
/**
* Utility class to make it easier to begin, commit, and rollback transactions.
*
* This can be used to handle cases where transaction support is optional.
* The second parameter of beginOptionalTransaction() will determine with a transaction
* is used or not. If a transaction is not used, the commit and rollback methods
* do not have any effect. Instead it simply makes the logic easier to follow
* by cutting down on the if statements based solely on whether a transaction
* is needed or not.
*
* @author Hans Lellelid <hans@xmpl.org> (Propel)
* @author Stephen Haberman <stephenh@chase3000.com> (Torque)
* @version $Revision: 536 $
* @package propel.util
*/
class Transaction {
/**
* Begin a transaction. This method will fallback gracefully to
* return a normal connection, if the database being accessed does
* not support transactions.
*
* @param string $dbName Name of database.
* @return Connection The Connection for the transaction.
* @throws PropelException
*/
public static function begin($dbName)
{
$con = Propel::getConnection($dbName);
try {
$con->setAutoCommit(false);
} catch (SQLException $e) {
throw new PropelException($e);
}
return $con;
}
/**
* Begin a transaction. This method will fallback gracefully to
* return a normal connection, if the database being accessed does
* not support transactions.
*
* @param sring $dbName Name of database.
* @param boolean $useTransaction If false, a transaction won't be used.
* @return Connection The Connection for the transaction.
* @throws PropelException
*/
public static function beginOptional($dbName, $useTransaction)
{
$con = Propel::getConnection($dbName);
try {
if ($useTransaction) {
$con->setAutoCommit(false);
}
} catch (SQLException $e) {
throw new PropelException($e);
}
return $con;
}
/**
* Commit a transaction. This method takes care of releasing the
* connection after the commit. In databases that do not support
* transactions, it only returns the connection.
*
* @param Connection $con The Connection for the transaction.
* @return void
* @throws PropelException
*/
public static function commit($con)
{
if ($con === null) {
throw new PropelException(
"Connection object was null. "
. "This could be due to a misconfiguration. "
. "Check the logs and Propel properties "
. "to better determine the cause.");
}
try {
if ($con->getAutoCommit() === false) {
$con->commit();
$con->setAutoCommit(true);
}
} catch (SQLException $e) {
throw new PropelException($e);
}
}
/**
* Roll back a transaction in databases that support transactions.
* It also releases the connection. In databases that do not support
* transactions, this method will log the attempt and release the
* connection.
*
* @param Connection $con The Connection for the transaction.
* @return void
* @throws PropelException
*/
public static function rollback($con)
{
if ($con === null) {
throw new PropelException(
"Connection object was null. "
. "This could be due to a misconfiguration. "
. "Check the logs and Propel properties "
. "to better determine the cause.");
}
try {
if ($con->getAutoCommit() === false) {
$con->rollback();
$con->setAutoCommit(true);
}
} catch (SQLException $e) {
Propel::log(
"An attempt was made to rollback a transaction "
. "but the database did not allow the operation to be "
. "rolled back: " . $e->getMessage(), Propel::LOG_ERR);
throw new PropelException($e);
}
}
/**
* Roll back a transaction without throwing errors if they occur.
*
* @param Connection $con The Connection for the transaction.
* @return void
*/
public static function safeRollback($con)
{
try {
Transaction::rollback($con);
} catch (PropelException $e) {
Propel::log("An error occured during rollback: " . $e->getMessage(), Propel::LOG_ERR);
}
}
}