<?php
/*
* $Id: PHP5BasicPeerBuilder.php 592 2007-03-02 21:41:42Z hans $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://propel.phpdb.org>.
*/
require_once 'propel/engine/builder/om/PeerBuilder.php';
/**
* Generates a PHP5 base Peer class for user object model (OM).
*
* This class produces the base peer class (e.g. BaseMyPeer) which contains all
* the custom-built query and manipulator methods.
*
* This class replaces the Peer.tpl, with the intent of being easier for users
* to customize (through extending & overriding).
*
* @author Hans Lellelid <hide@address.com>
* @package propel.engine.builder.om.php5
*/
class PHP5BasicPeerBuilder extends PeerBuilder {
/**
* Returns the name of the current class being built.
* @return string
*/
public function getClassname()
{
return $this->getBuildProperty('basePrefix') . $this->getStubPeerBuilder()->getClassname();
}
/**
* Gets the package for the [base] peer classes.
* @return string
*/
public function getPackage()
{
return parent::getPackage() . ".om";
}
/**
* Adds the include() statements for files that this class depends on or utilizes.
* @param string &$script The script will be modified in this method.
*/
protected function addIncludes(&$script) {
$table = $this->getTable();
$basePeerFile = $this->getFilePath($this->basePeerClass);
$objectFile = $this->getStubObjectBuilder()->getClassFilePath();
$script .= "
require_once '$basePeerFile';
// The object class -- needed for instanceof checks in this class.
// actual class may be a subclass -- as returned by ".$this->getPeerClassname()."::getOMClass()
include_once '$objectFile';";
$script .= "
";
} // addIncludes()
/**
* Adds class phpdoc comment and openning of class.
* @param string &$script The script will be modified in this method.
*/
protected function addClassOpen(&$script) {
$tableName = $this->getTable()->getName();
$tableDesc = $this->getTable()->getDescription();
$script .= "
/**
* Base static class for performing query and update operations on the '$tableName' table.
*
* $tableDesc
*";
if ($this->getBuildProperty('addTimeStamp')) {
$now = strftime('%c');
$script .= "
* This class was autogenerated by Propel on:
*
* $now
*";
}
$script .= "
* @package ".$this->getPackage()."
*/
abstract class ".$this->getClassname()." {
";
}
/**
* Closes class.
* Adds closing brace at end of class and the static map builder registration code.
* @param string &$script The script will be modified in this method.
* @see addStaticMapBuilderRegistration()
*/
protected function addClassClose(&$script)
{
$script .= "
} // " . $this->getClassname() . "
";
$this->addStaticMapBuilderRegistration($script);
}
/**
* Adds the static map builder registraction code.
* @param string &$script The script will be modified in this method.
*/
protected function addStaticMapBuilderRegistration(&$script)
{
$table = $this->getTable();
$mapBuilderFile = $this->getMapBuilderBuilder()->getClassFilePath();
$script .= "
// static code to register the map builder for this Peer with the main Propel class
if (Propel::isInit()) {
// the MapBuilder classes register themselves with Propel during initialization
// so we need to load them here.
try {
".$this->getClassname()."::getMapBuilder();
} catch (Exception \$e) {
Propel::log('Could not initialize Peer: ' . \$e->getMessage(), Propel::LOG_ERR);
}
} else {
// even if Propel is not yet initialized, the map builder class can be registered
// now and then it will be loaded when Propel initializes.
require_once '$mapBuilderFile';
Propel::registerMapBuilder('".$this->getMapBuilderBuilder()->getClasspath()."');
}
";
}
/**
* Adds constant and variable declarations that go at the top of the class.
* @param string &$script The script will be modified in this method.
* @see addColumnNameConstants()
*/
protected function addConstantsAndAttributes(&$script)
{
$tableName = $this->getTable()->getName();
$dbName = $this->getDatabase()->getName();
$script .= "
/** the default database name for this class */
const DATABASE_NAME = '$dbName';
/** the table name for this class */
const TABLE_NAME = '$tableName';
/** A class that can be returned by this peer. */
const CLASS_DEFAULT = '".$this->getStubObjectBuilder()->getClasspath()."';
/** The total number of columns. */
const NUM_COLUMNS = ".$this->getTable()->getNumColumns().";
/** The number of lazy-loaded columns. */
const NUM_LAZY_LOAD_COLUMNS = ".$this->getTable()->getNumLazyLoadColumns().";
";
$this->addColumnNameConstants($script);
$this->addInheritanceColumnConstants($script);
$script .= "
/** The PHP to DB Name Mapping */
private static \$phpNameMap = null;
";
$this->addFieldNamesAttribute($script);
$this->addFieldKeysAttribute($script);
}
/**
* Adds the COLUMN_NAME contants to the class definition.
* @param string &$script The script will be modified in this method.
*/
protected function addColumnNameConstants(&$script)
{
foreach ($this->getTable()->getColumns() as $col) {
$script .= "
/** the column name for the ".strtoupper($col->getName()) ." field */
const ".$this->getColumnName($col) ." = '".$this->getTable()->getName().".".strtoupper($col->getName())."';
";
} // foreach
}
protected function addFieldNamesAttribute(&$script)
{
$table = $this->getTable();
$tableColumns = $table->getColumns();
$tablePhpname = $table->getPhpName();
$script .= "
/**
* holds an array of fieldnames
*
* first dimension keys are the type constants
* e.g. self::\$fieldNames[self::TYPE_PHPNAME][0] = 'Id'
*/
private static \$fieldNames = array (
BasePeer::TYPE_PHPNAME => array (";
foreach ($tableColumns as $col) {
$script .= "'".$col->getPhpName()."', ";
}
$script .= "),
BasePeer::TYPE_COLNAME => array (";
foreach ($tableColumns as $col) {
$script .= $this->getColumnConstant($col).", ";
}
$script .= "),
BasePeer::TYPE_FIELDNAME => array (";
foreach ($tableColumns as $col) {
$script .= "'".$col->getName()."', ";
}
$script .= "),
BasePeer::TYPE_NUM => array (";
foreach ($tableColumns as $num => $col) {
$script .= "$num, ";
}
$script .= ")
);
";
}
protected function addFieldKeysAttribute(&$script)
{
$table = $this->getTable();
$tableColumns = $table->getColumns();
$tablePhpname = $table->getPhpName();
$script .= "
/**
* holds an array of keys for quick access to the fieldnames array
*
* first dimension keys are the type constants
* e.g. self::\$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0
*/
private static \$fieldKeys = array (
BasePeer::TYPE_PHPNAME => array (";
foreach ($tableColumns as $num => $col) {
$script .= "'".$col->getPhpName()."' => $num, ";
}
$script .= "),
BasePeer::TYPE_COLNAME => array (";
foreach ($tableColumns as $num => $col) {
$script .= $this->getColumnConstant($col)." => $num, ";
}
$script .= "),
BasePeer::TYPE_FIELDNAME => array (";
foreach ($tableColumns as $num => $col) {
$script .= "'".$col->getName()."' => $num, ";
}
$script .= "),
BasePeer::TYPE_NUM => array (";
foreach ($tableColumns as $num => $col) {
$script .= "$num, ";
}
$script .= ")
);
";
} // addFielKeysAttribute
protected function addGetFieldNames(&$script)
{
$script .= "
/**
* Returns an array of of field names.
*
* @param string \$type The type of fieldnames to return:
* One of the class type constants TYPE_PHPNAME,
* TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM
* @return array A list of field names
*/
static public function getFieldNames(\$type = BasePeer::TYPE_PHPNAME)
{
if (!array_key_exists(\$type, self::\$fieldNames)) {
throw new PropelException('Method getFieldNames() expects the parameter \$type to be one of the class constants TYPE_PHPNAME, TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM. ' . \$type . ' was given.');
}
return self::\$fieldNames[\$type];
}
";
} // addGetFieldNames()
protected function addTranslateFieldName(&$script)
{
$script .= "
/**
* Translates a fieldname to another type
*
* @param string \$name field name
* @param string \$fromType One of the class type constants TYPE_PHPNAME,
* TYPE_COLNAME, TYPE_FIELDNAME, TYPE_NUM
* @param string \$toType One of the class type constants
* @return string translated name of the field.
*/
static public function translateFieldName(\$name, \$fromType, \$toType)
{
\$toNames = self::getFieldNames(\$toType);
\$key = isset(self::\$fieldKeys[\$fromType][\$name]) ? self::\$fieldKeys[\$fromType][\$name] : null;
if (\$key === null) {
throw new PropelException(\"'\$name' could not be found in the field names of type '\$fromType'. These are: \" . print_r(self::\$fieldKeys[\$fromType], true));
}
return \$toNames[\$key];
}
";
} // addTranslateFieldName()
/**
* Adds the getMapBuilder() method.
* @param string &$script The script will be modified in this method.
*/
protected function addGetMapBuilder(&$script)
{
$script .= "
/**
* @return MapBuilder the map builder for this peer
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function getMapBuilder()
{
include_once '" . $this->getMapBuilderBuilder()->getClassFilePath()."';
return ".$this->basePeerClassname."::getMapBuilder('". $this->getMapBuilderBuilder()->getClasspath() ."');
}";
}
/**
* Adds the getPhpNameMap() method.
* @param string &$script The script will be modified in this method.
* @todo Replace with static version (this can be built at build-time).
*/
protected function addGetPhpNameMap(&$script)
{
$script .= "
/**
* Gets a map (hash) of PHP names to DB column names.
*
* @return array The PHP to DB name map for this peer
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
* @deprecated Use the getFieldNames() and translateFieldName() methods instead of this.
*/
public static function getPhpNameMap()
{
if (self::\$phpNameMap === null) {
\$map = ".$this->getTable()->getPhpName()."Peer::getTableMap();
\$columns = \$map->getColumns();
\$nameMap = array();
foreach (\$columns as \$column) {
\$nameMap[\$column->getPhpName()] = \$column->getColumnName();
}
self::\$phpNameMap = \$nameMap;
}
return self::\$phpNameMap;
}";
}
/**
* Adds the CLASSKEY_* and CLASSNAME_* constants used for inheritance.
* @param string &$script The script will be modified in this method.
*/
public function addInheritanceColumnConstants(&$script)
{
if ($this->getTable()->getChildrenColumn()) {
$col = $this->getTable()->getChildrenColumn();
$tfc = $this->getTable()->getPhpName();
$cfc = $col->getPhpName();
if ($col->isEnumeratedClasses()) {
if ($col->isPrimitiveNumeric()) $quote = "";
else $quote = '"';
foreach ($col->getChildren() as $child) {
$childBuilder = $this->getMultiExtendObjectBuilder();
$childBuilder->setChild($child);
$script .= "
/** A key representing a particular subclass */
const CLASSKEY_".strtoupper($child->getKey())." = '" . $child->getKey() . "';
";
if (strtoupper($child->getClassname()) != strtoupper($child->getKey())) {
$script .= "
/** A key representing a particular subclass */
const CLASSKEY_".strtoupper($child->getClassname())." = '" . $child->getKey() . "';
";
}
$script .= "
/** A class that can be returned by this peer. */
const CLASSNAME_".strtoupper($child->getKey())." = '". $childBuilder->getClasspath() . "';
";
} /* foreach children */
} /* if col->isenumerated...() */
} /* if table->getchildrencolumn() */
} //
/**
* Adds the alias() utility method.
* @param string &$script The script will be modified in this method.
*/
protected function addAlias(&$script)
{
$script .= "
/**
* Convenience method which changes table.column to alias.column.
*
* Using this method you can maintain SQL abstraction while using column aliases.
* <code>
* \$c->addAlias(\"alias1\", TablePeer::TABLE_NAME);
* \$c->addJoin(TablePeer::alias(\"alias1\", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN);
* </code>
* @param string \$alias The alias for the current table.
* @param string \$column The column name for current table. (i.e. ".$this->getTable()->getPhpName()."Peer::COLUMN_NAME).
* @return string
*/
public static function alias(\$alias, \$column)
{
return str_replace(".$this->getPeerClassname()."::TABLE_NAME.'.', \$alias.'.', \$column);
}
";
} // addAliasMethod
/**
* Adds the addSelectColumns() method.
* @param string &$script The script will be modified in this method.
*/
protected function addAddSelectColumns(&$script)
{
$script .= "
/**
* Add all the columns needed to create a new object.
*
* Note: any columns that were marked with lazyLoad=\"true\" in the
* XML schema will not be added to the select list and only loaded
* on demand.
*
* @param criteria object containing the columns to add.
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function addSelectColumns(Criteria \$criteria)
{
";
foreach ($this->getTable()->getColumns() as $col) {
if (!$col->isLazyLoad()) {
$script .= "
\$criteria->addSelectColumn(".$this->getPeerClassname()."::".$this->getColumnName($col).");
";
} // if !col->isLazyLoad
} // foreach
$script .="
}
";
} // addAddSelectColumns()
/**
* Adds the COUNT constants.
* @param string &$script The script will be modified in this method.
*/
protected function addCountConstants(&$script)
{
$table = $this->getTable();
$count_col = "*";
/*
* FIXME
* (HL) wanted to remove this because AFAIK count(*) is generally
* optimized in databases, and furthermore the code below isn't correct
* (multi-pkey needs to be accounted for)....
*/
if ($table->hasPrimaryKey()) {
$pk = $table->getPrimaryKey();
$count_col = $table->getName().".".strtoupper($pk[0]->getName());
}
$script .= "
const COUNT = 'COUNT($count_col)';
const COUNT_DISTINCT = 'COUNT(DISTINCT $count_col)';
";
}
/**
* Adds the doCount() method.
* @param string &$script The script will be modified in this method.
*/
protected function addDoCount(&$script)
{
$script .= "
/**
* Returns the number of rows matching criteria.
*
* @param Criteria \$criteria
* @param boolean \$distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria).
* @param Connection \$con
* @return int Number of matching rows.
*/
public static function doCount(Criteria \$criteria, \$distinct = false, \$con = null)
{
// we're going to modify criteria, so copy it first
\$criteria = clone \$criteria;
// clear out anything that might confuse the ORDER BY clause
\$criteria->clearSelectColumns()->clearOrderByColumns();
if (\$distinct || in_array(Criteria::DISTINCT, \$criteria->getSelectModifiers())) {
\$criteria->addSelectColumn(".$this->getPeerClassname()."::COUNT_DISTINCT);
} else {
\$criteria->addSelectColumn(".$this->getPeerClassname()."::COUNT);
}
// just in case we're grouping: add those columns to the select statement
foreach(\$criteria->getGroupByColumns() as \$column)
{
\$criteria->addSelectColumn(\$column);
}
\$rs = ".$this->getPeerClassname()."::doSelectRS(\$criteria, \$con);
if (\$rs->next()) {
return \$rs->getInt(1);
} else {
// no rows returned; we infer that means 0 matches.
return 0;
}
}";
}
/**
* Adds the doSelectOne() method.
* @param string &$script The script will be modified in this method.
*/
protected function addDoSelectOne(&$script)
{
$script .= "
/**
* Method to select one object from the DB.
*
* @param Criteria \$criteria object used to create the SELECT statement.
* @param Connection \$con
* @return ".$this->getTable()->getPhpName()."
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doSelectOne(Criteria \$criteria, \$con = null)
{
\$critcopy = clone \$criteria;
\$critcopy->setLimit(1);
\$objects = ".$this->getPeerClassname()."::doSelect(\$critcopy, \$con);
if (\$objects) {
return \$objects[0];
}
return null;
}";
}
/**
* Adds the doSelect() method.
* @param string &$script The script will be modified in this method.
*/
protected function addDoSelect(&$script)
{
$script .= "
/**
* Method to do selects.
*
* @param Criteria \$criteria The Criteria object used to build the SELECT statement.
* @param Connection \$con
* @return array Array of selected Objects
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doSelect(Criteria \$criteria, \$con = null)
{
return ".$this->getPeerClassname()."::populateObjects(".$this->getPeerClassname()."::doSelectRS(\$criteria, \$con));
}";
}
/**
* Adds the doSelectRS() method.
* @param string &$script The script will be modified in this method.
*/
protected function addDoSelectRS(&$script)
{
$script .= "
/**
* Prepares the Criteria object and uses the parent doSelect()
* method to get a ResultSet.
*
* Use this method directly if you want to just get the resultset
* (instead of an array of objects).
*
* @param Criteria \$criteria The Criteria object used to build the SELECT statement.
* @param Connection \$con the connection to use
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
* @return ResultSet The resultset object with numerically-indexed fields.
* @see ".$this->basePeerClassname."::doSelect()
*/
public static function doSelectRS(Criteria \$criteria, \$con = null)
{
if (\$con === null) {
\$con = Propel::getConnection(self::DATABASE_NAME);
}
if (!\$criteria->getSelectColumns()) {
\$criteria = clone \$criteria;
".$this->getPeerClassname()."::addSelectColumns(\$criteria);
}
// Set the correct dbName
\$criteria->setDbName(self::DATABASE_NAME);
// BasePeer returns a Creole ResultSet, set to return
// rows indexed numerically.
return ".$this->basePeerClassname."::doSelect(\$criteria, \$con);
}";
}
/**
* Adds the populateObjects() method.
* @param string &$script The script will be modified in this method.
*/
protected function addPopulateObjects(&$script)
{
$table = $this->getTable();
$script .= "
/**
* The returned array will contain objects of the default type or
* objects that inherit from the default.
*
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function populateObjects(ResultSet \$rs)
{
\$results = array();
";
if (!$table->getChildrenColumn()) {
$script .= "
// set the class once to avoid overhead in the loop
\$cls = ".$this->getPeerClassname()."::getOMClass();
\$cls = Propel::import(\$cls);";
}
$script .= "
// populate the object(s)
while(\$rs->next()) {
";
if ($table->getChildrenColumn()) {
$script .= "
// class must be set each time from the record row
\$cls = Propel::import(".$this->getPeerClassname()."::getOMClass(\$rs, 1));
\$obj = new \$cls();
\$obj->hydrate(\$rs);
\$results[] = \$obj;
";
} else {
$script .= "
\$obj = new \$cls();
\$obj->hydrate(\$rs);
\$results[] = \$obj;
";
}
$script .= "
}
return \$results;
}";
}
/**
* Adds a getOMClass() for non-abstract tables that have inheritance.
* @param string &$script The script will be modified in this method.
*/
protected function addGetOMClass_Inheritance(&$script)
{
$col = $this->getTable()->getChildrenColumn();
$script .= "
/**
* The returned Class will contain objects of the default type or
* objects that inherit from the default.
*
* @param ResultSet \$rs ResultSet with pointer to record containing om class.
* @param int \$colnum Column to examine for OM class information (first is 1).
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function getOMClass(ResultSet \$rs, \$colnum)
{
try {
";
if ($col->isEnumeratedClasses()) {
$script .= "
\$omClass = null;
\$classKey = \$rs->getString(\$colnum - 1 + " . $col->getPosition() . ");
switch(\$classKey) {
";
foreach ($col->getChildren() as $child) {
$script .= "
case self::CLASSKEY_".strtoupper($child->getKey()).":
\$omClass = self::CLASSNAME_".strtoupper($child->getKey()).";
break;
";
} /* foreach */
$script .= "
default:
\$omClass = self::CLASS_DEFAULT;
";
$script .= "
} // switch
";
} else { /* if not enumerated */
$script .= "
\$omClass = Propel::import(\$rs->getString(\$colnum - 1 + ".$col->getPosition()."));
";
}
$script .= "
} catch (Exception \$e) {
throw new PropelException('Unable to get OM class.', \$e);
}
return \$omClass;
}
";
}
/**
* Adds a getOMClass() signature for abstract tables that have inheritance.
* @param string &$script The script will be modified in this method.
*/
protected function addGetOMClass_Inheritance_Abstract(&$script)
{
$script .= "
/**
* The returned Class will contain objects of the default type or
* objects that inherit from the default.
*
* This method must be overridden by the stub subclass, because
* ".$this->getTable()->getPhpName()." is declared abstract in the schema.
*
* @param ResultSet \$rs ResultSet with pointer to record containing om class.
* @param int \$colnum Column to examine for OM class information (first is 1).
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
abstract public static function getOMClass();
";
}
/**
* Adds a getOMClass() for non-abstract tables that do note use inheritance.
* @param string &$script The script will be modified in this method.
*/
protected function addGetOMClass_NoInheritance(&$script)
{
$script .= "
/**
* The class that the Peer will make instances of.
*
* This uses a dot-path notation which is tranalted into a path
* relative to a location on the PHP include_path.
* (e.g. path.to.MyClass -> 'path/to/MyClass.php')
*
* @return string path.to.ClassName
*/
public static function getOMClass()
{
return ".$this->getPeerClassname()."::CLASS_DEFAULT;
}
";
}
/**
* Adds a getOMClass() signature for abstract tables that do not have inheritance.
* @param string &$script The script will be modified in this method.
*/
protected function addGetOMClass_NoInheritance_Abstract(&$script)
{
$script .= "
/**
* The class that the Peer will make instances of.
*
* This method must be overridden by the stub subclass, because
* ".$this->getTable()->getPhpName()." is declared abstract in the schema.
*/
abstract public static function getOMClass();
";
}
/**
* Adds the doInsert() method.
* @param string &$script The script will be modified in this method.
*/
protected function addDoInsert(&$script)
{
$table = $this->getTable();
$script .= "
/**
* Method perform an INSERT on the database, given a ".$table->getPhpName()." or Criteria object.
*
* @param mixed \$values Criteria or ".$table->getPhpName()." object containing data that is used to create the INSERT statement.
* @param Connection \$con the connection to use
* @return mixed The new primary key.
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doInsert(\$values, \$con = null)
{
if (\$con === null) {
\$con = Propel::getConnection(self::DATABASE_NAME);
}
if (\$values instanceof Criteria) {
\$criteria = clone \$values; // rename for clarity
} else {
\$criteria = \$values->buildCriteria(); // build Criteria from ".$table->getPhpName()." object
}
";
foreach ($table->getColumns() as $col) {
$cfc = $col->getPhpName();
if ($col->isPrimaryKey() && $col->isAutoIncrement() && $table->getIdMethod() != "none") {
$script .= "
\$criteria->remove(".$this->getColumnConstant($col)."); // remove pkey col since this table uses auto-increment
";
}
}
$script .= "
// Set the correct dbName
\$criteria->setDbName(self::DATABASE_NAME);
try {
// use transaction because \$criteria could contain info
// for more than one table (I guess, conceivably)
\$con->begin();
\$pk = ".$this->basePeerClassname."::doInsert(\$criteria, \$con);
\$con->commit();
} catch(PropelException \$e) {
\$con->rollback();
throw \$e;
}
return \$pk;
}
";
}
/**
* Adds the doUpdate() method.
* @param string &$script The script will be modified in this method.
*/
protected function addDoUpdate(&$script)
{
$table = $this->getTable();
$script .= "
/**
* Method perform an UPDATE on the database, given a ".$table->getPhpName()." or Criteria object.
*
* @param mixed \$values Criteria or ".$table->getPhpName()." object containing data that is used to create the UPDATE statement.
* @param Connection \$con The connection to use (specify Connection object to exert more control over transactions).
* @return int The number of affected rows (if supported by underlying database driver).
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doUpdate(\$values, \$con = null)
{
if (\$con === null) {
\$con = Propel::getConnection(self::DATABASE_NAME);
}
\$selectCriteria = new Criteria(self::DATABASE_NAME);
if (\$values instanceof Criteria) {
\$criteria = clone \$values; // rename for clarity
";
foreach ($table->getColumns() as $col) {
if($col->isPrimaryKey()) {
$script .= "
\$comparison = \$criteria->getComparison(".$this->getColumnConstant($col).");
\$selectCriteria->add(".$this->getColumnConstant($col).", \$criteria->remove(".$this->getColumnConstant($col)."), \$comparison);
";
} /* if col is prim key */
} /* foreach */
$script .= "
} else { // \$values is ".$table->getPhpName()." object
\$criteria = \$values->buildCriteria(); // gets full criteria
\$selectCriteria = \$values->buildPkeyCriteria(); // gets criteria w/ primary key(s)
}
// set the correct dbName
\$criteria->setDbName(self::DATABASE_NAME);
return {$this->basePeerClassname}::doUpdate(\$selectCriteria, \$criteria, \$con);
}
";
}
/**
* Adds the doDeleteAll() method.
* @param string &$script The script will be modified in this method.
*/
protected function addDoDeleteAll(&$script)
{
$table = $this->getTable();
$script .= "
/**
* Method to DELETE all rows from the ".$table->getName()." table.
*
* @return int The number of affected rows (if supported by underlying database driver).
*/
public static function doDeleteAll(\$con = null)
{
if (\$con === null) {
\$con = Propel::getConnection(self::DATABASE_NAME);
}
\$affectedRows = 0; // initialize var to track total num of affected rows
try {
// use transaction because \$criteria could contain info
// for more than one table or we could emulating ON DELETE CASCADE, etc.
\$con->begin();
";
if ($this->isDeleteCascadeEmulationNeeded()) {
$script .="\$affectedRows += ".$this->getPeerClassname()."::doOnDeleteCascade(new Criteria(), \$con);
";
}
if ($this->isDeleteSetNullEmulationNeeded()) {
$script .= $this->getPeerClassname() . "::doOnDeleteSetNull(new Criteria(), \$con);
";
}
$script .= "\$affectedRows += BasePeer::doDeleteAll(".$this->getPeerClassname()."::TABLE_NAME, \$con);
\$con->commit();
return \$affectedRows;
} catch (PropelException \$e) {
\$con->rollback();
throw \$e;
}
}
";
}
/**
* Adds the doDelete() method.
* @param string &$script The script will be modified in this method.
*/
protected function addDoDelete(&$script)
{
$table = $this->getTable();
$script .= "
/**
* Method perform a DELETE on the database, given a ".$table->getPhpName()." or Criteria object OR a primary key value.
*
* @param mixed \$values Criteria or ".$table->getPhpName()." object or primary key or array of primary keys
* which is used to create the DELETE statement
* @param Connection \$con the connection to use
* @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows
* if supported by native driver or if emulated using Propel.
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doDelete(\$values, \$con = null)
{
if (\$con === null) {
\$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME);
}
if (\$values instanceof Criteria) {
\$criteria = clone \$values; // rename for clarity
} elseif (\$values instanceof ".$table->getPhpName().") {
";
if (count($table->getPrimaryKey()) > 0) {
$script .= "
\$criteria = \$values->buildPkeyCriteria();";
} else {
$script .= "
\$criteria = \$values->buildCriteria();";
}
$script .= "
} else {
// it must be the primary key
\$criteria = new Criteria(self::DATABASE_NAME);";
if (count($table->getPrimaryKey()) === 1) {
$pkey = $table->getPrimaryKey();
$col = array_shift($pkey);
$script .= "
\$criteria->add(".$this->getColumnConstant($col).", (array) \$values, Criteria::IN);";
} else {
$script .= "
// primary key is composite; we therefore, expect
// the primary key passed to be an array of pkey
// values
if(count(\$values) == count(\$values, COUNT_RECURSIVE))
{
// array is not multi-dimensional
\$values = array(\$values);
}
\$vals = array();
foreach(\$values as \$value)
{
";
$i=0;
foreach($table->getPrimaryKey() as $col) {
$script .= "
\$vals[$i][] = \$value[$i];";
$i++;
}
$script .= "
}
";
$i=0;
foreach($table->getPrimaryKey() as $col) {
$script .= "
\$criteria->add(".$this->getColumnConstant($col).", \$vals[$i], Criteria::IN);";
$i++;
}
} /* if count(table->getPrimaryKeys()) */
$script .= "
}
// Set the correct dbName
\$criteria->setDbName(self::DATABASE_NAME);
\$affectedRows = 0; // initialize var to track total num of affected rows
try {
// use transaction because \$criteria could contain info
// for more than one table or we could emulating ON DELETE CASCADE, etc.
\$con->begin();
";
if ($this->isDeleteCascadeEmulationNeeded()) {
$script .= "\$affectedRows += ".$this->getPeerClassname()."::doOnDeleteCascade(\$criteria, \$con);";
}
if ($this->isDeleteSetNullEmulationNeeded()) {
$script .= $this->getPeerClassname() . "::doOnDeleteSetNull(\$criteria, \$con);";
}
$script .= "
\$affectedRows += {$this->basePeerClassname}::doDelete(\$criteria, \$con);
\$con->commit();
return \$affectedRows;
} catch (PropelException \$e) {
\$con->rollback();
throw \$e;
}
}
";
}
/**
* Adds the doOnDeleteCascade() method, which provides ON DELETE CASCADE emulation.
* @param string &$script The script will be modified in this method.
*/
protected function addDoOnDeleteCascade(&$script)
{
$table = $this->getTable();
$script .= "
/**
* This is a method for emulating ON DELETE CASCADE for DBs that don't support this
* feature (like MySQL or SQLite).
*
* This method is not very speedy because it must perform a query first to get
* the implicated records and then perform the deletes by calling those Peer classes.
*
* This method should be used within a transaction if possible.
*
* @param Criteria \$criteria
* @param Connection \$con
* @return int The number of affected rows (if supported by underlying database driver).
*/
protected static function doOnDeleteCascade(Criteria \$criteria, Connection \$con)
{
// initialize var to track total num of affected rows
\$affectedRows = 0;
// first find the objects that are implicated by the \$criteria
\$objects = ".$this->getPeerClassname()."::doSelect(\$criteria, \$con);
foreach(\$objects as \$obj) {
";
foreach ($table->getReferrers() as $fk) {
// $fk is the foreign key in the other table, so localTableName will
// actually be the table name of other table
$tblFK = $fk->getTable();
$joinedTablePeerBuilder = OMBuilder::getNewPeerBuilder($tblFK);
$tblFKPackage = $joinedTablePeerBuilder->getStubPeerBuilder()->getPackage();
if (!$tblFK->isForReferenceOnly()) {
// we can't perform operations on tables that are
// not within the schema (i.e. that we have no map for, etc.)
$fkClassName = $tblFK->getPhpName();
// i'm not sure whether we can allow delete cascade for foreign keys
// within the same table? perhaps we can?
if ( $fk->getOnDelete() == ForeignKey::CASCADE && $tblFK->getName() != $table->getName()) {
// backwards on purpose
$columnNamesF = $fk->getLocalColumns();
$columnNamesL = $fk->getForeignColumns();
$script .= "
include_once '".$this->getFilePath($tblFKPackage, $tblFK->getPhpName())."';
// delete related $fkClassName objects
\$c = new Criteria();
";
for($x=0,$xlen=count($columnNamesF); $x < $xlen; $x++) {
$columnFK = $tblFK->getColumn($columnNamesF[$x]);
$columnL = $table->getColumn($columnNamesL[$x]);
$script .= "
\$c->add(".$joinedTablePeerBuilder->getColumnConstant($columnFK) .", \$obj->get".$columnL->getPhpName()."());";
}
$script .= "
\$affectedRows += ".$joinedTablePeerBuilder->getPeerClassname()."::doDelete(\$c, \$con);";
} // if cascade && fkey table name != curr table name
} // if not for ref only
} // foreach foreign keys
$script .= "
}
return \$affectedRows;
}
";
} // end addDoOnDeleteCascade
/**
* Adds the doOnDeleteSetNull() method, which provides ON DELETE SET NULL emulation.
* @param string &$script The script will be modified in this method.
*/
protected function addDoOnDeleteSetNull(&$script)
{
$table = $this->getTable();
$script .= "
/**
* This is a method for emulating ON DELETE SET NULL DBs that don't support this
* feature (like MySQL or SQLite).
*
* This method is not very speedy because it must perform a query first to get
* the implicated records and then perform the deletes by calling those Peer classes.
*
* This method should be used within a transaction if possible.
*
* @param Criteria \$criteria
* @param Connection \$con
* @return void
*/
protected static function doOnDeleteSetNull(Criteria \$criteria, Connection \$con)
{
// first find the objects that are implicated by the \$criteria
\$objects = ".$this->getPeerClassname()."::doSelect(\$criteria, \$con);
foreach(\$objects as \$obj) {
";
// This logic is almost exactly the same as that in doOnDeleteCascade()
// it may make sense to refactor this, provided that thigns don't
// get too complicated.
foreach ($table->getReferrers() as $fk) {
// $fk is the foreign key in the other table, so localTableName will
// actually be the table name of other table
$tblFK = $fk->getTable();
$refTablePeerBuilder = OMBuilder::getNewPeerBuilder($tblFK);
if (!$tblFK->isForReferenceOnly()) {
// we can't perform operations on tables that are
// not within the schema (i.e. that we have no map for, etc.)
$fkClassName = $tblFK->getPhpName();
// i'm not sure whether we can allow delete setnull for foreign keys
// within the same table? perhaps we can?
if ( $fk->getOnDelete() == ForeignKey::SETNULL &&
$fk->getTable()->getName() != $table->getName()) {
// backwards on purpose
$columnNamesF = $fk->getLocalColumns();
$columnNamesL = $fk->getForeignColumns(); // should be same num as foreign
$script .= "
// set fkey col in related $fkClassName rows to NULL
\$selectCriteria = new Criteria(".$this->getPeerClassname()."::DATABASE_NAME);
\$updateValues = new Criteria(".$this->getPeerClassname()."::DATABASE_NAME);";
for ($x=0,$xlen=count($columnNamesF); $x < $xlen; $x++) {
$columnFK = $tblFK->getColumn($columnNamesF[$x]);
$columnL = $table->getColumn($columnNamesL[$x]);
$script .= "
\$selectCriteria->add(".$refTablePeerBuilder->getColumnConstant($columnFK).", \$obj->get".$columnL->getPhpName()."());
\$updateValues->add(".$refTablePeerBuilder->getColumnConstant($columnFK).", null);
";
}
$script .= "
{$this->basePeerClassname}::doUpdate(\$selectCriteria, \$updateValues, \$con); // use BasePeer because generated Peer doUpdate() methods only update using pkey
";
} // if setnull && fkey table name != curr table name
} // if not for ref only
} // foreach foreign keys
$script .= "
}
}
";
}
/**
* Adds the doValidate() method.
* @param string &$script The script will be modified in this method.
*/
protected function addDoValidate(&$script)
{
$table = $this->getTable();
$script .= "
/**
* Validates all modified columns of given ".$table->getPhpName()." object.
* If parameter \$columns is either a single column name or an array of column names
* than only those columns are validated.
*
* NOTICE: This does not apply to primary or foreign keys for now.
*
* @param ".$table->getPhpName()." \$obj The object to validate.
* @param mixed \$cols Column name or array of column names.
*
* @return mixed TRUE if all columns are valid or the error message of the first invalid column.
*/
public static function doValidate(".$table->getPhpName()." \$obj, \$cols = null)
{
\$columns = array();
if (\$cols) {
\$dbMap = Propel::getDatabaseMap(".$this->getPeerClassname()."::DATABASE_NAME);
\$tableMap = \$dbMap->getTable(".$this->getPeerClassname()."::TABLE_NAME);
if (! is_array(\$cols)) {
\$cols = array(\$cols);
}
foreach(\$cols as \$colName) {
if (\$tableMap->containsColumn(\$colName)) {
\$get = 'get' . \$tableMap->getColumn(\$colName)->getPhpName();
\$columns[\$colName] = \$obj->\$get();
}
}
} else {
";
foreach ($table->getValidators() as $val) {
$col = $val->getColumn();
if (!$col->isAutoIncrement()) {
$script .= "
if (\$obj->isNew() || \$obj->isColumnModified(".$this->getColumnConstant($col)."))
\$columns[".$this->getColumnConstant($col)."] = \$obj->get".$col->getPhpName()."();
";
} // if
} // foreach
$script .= "
}
return {$this->basePeerClassname}::doValidate(".$this->getPeerClassname()."::DATABASE_NAME, ".$this->getPeerClassname()."::TABLE_NAME, \$columns);
}
";
} // end addDoValidate()
/**
* Adds the retrieveByPK method for tables with single-column primary key.
* @param string &$script The script will be modified in this method.
*/
protected function addRetrieveByPK_SinglePK(&$script)
{
$table = $this->getTable();
$script .= "
/**
* Retrieve a single object by pkey.
*
* @param mixed \$pk the primary key.
* @param Connection \$con the connection to use
* @return " . $table->getPhpName() . "
*/
public static function ".$this->getRetrieveMethodName()."(\$pk, \$con = null)
{
if (\$con === null) {
\$con = Propel::getConnection(self::DATABASE_NAME);
}
\$criteria = new Criteria(".$this->getPeerClassname()."::DATABASE_NAME);
";
if (count($table->getPrimaryKey()) === 1) {
$pkey = $table->getPrimaryKey();
$col = array_shift($pkey);
$script .= "
\$criteria->add(".$this->getColumnConstant($col).", \$pk);
";
} else {
// primary key is composite; we therefore, expect
// the primary key passed to be an array of pkey
// values
$i=0;
foreach($table->getPrimaryKey() as $col) {
$script .= "
\$criteria->add(".$this->getColumnConstant($col).", \$pk[$i]);";
$i++;
}
} /* if count(table.PrimaryKeys) */
$script .= "
\$v = ".$this->getPeerClassname()."::doSelect(\$criteria, \$con);
return !empty(\$v) > 0 ? \$v[0] : null;
}
";
}
/**
* Adds the retrieveByPKs method for tables with single-column primary key.
* @param string &$script The script will be modified in this method.
*/
protected function addRetrieveByPKs_SinglePK(&$script)
{
$table = $this->getTable();
$script .= "
/**
* Retrieve multiple objects by pkey.
*
* @param array \$pks List of primary keys
* @param Connection \$con the connection to use
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function ".$this->getRetrieveMethodName()."s(\$pks, \$con = null)
{
if (\$con === null) {
\$con = Propel::getConnection(self::DATABASE_NAME);
}
\$objs = null;
if (empty(\$pks)) {
\$objs = array();
} else {
\$criteria = new Criteria();";
if (count($table->getPrimaryKey()) == 1) {
$k1 = $table->getPrimaryKey();
$script .= "
\$criteria->add(".$this->getColumnConstant($k1[0]).", \$pks, Criteria::IN);";
} else {
$script .= "
foreach(\$pks as \$pk) {";
$i = 0;
foreach($table->getPrimaryKey() as $col) {
$script .= "
\$c{$i} = \$criteria->getNewCriterion(".$this->getPeerClassname($col).", \$pk[$i], Criteria::EQUAL);";
$j = $i - 1;
if ($i > 0) {
$script .= "
\$c{$j}->addAnd(\$c{$i});";
} /* if $i > 0 */
$i++;
} /* foreach */
$script .= "
\$criteria->addOr(\$c0);
}";
} /* if count prim keys == 1 */
$script .= "
\$objs = ".$this->getPeerClassname()."::doSelect(\$criteria, \$con);
}
return \$objs;
}
";
}
/**
* Adds the retrieveByPK method for tables with multi-column primary key.
* @param string &$script The script will be modified in this method.
*/
protected function addRetrieveByPK_MultiPK(&$script)
{
$table = $this->getTable();
$script .= "
/**
* Retrieve object using using composite pkey values.
* ";
foreach ($table->getPrimaryKey() as $col) {
$clo = strtolower($col->getName());
$cptype = $col->getPhpNative();
$script .= "@param $cptype $".$clo."
";
}
$script .= "
* @param Connection \$con
* @return ".$table->getPhpName()."
*/
public static function ".$this->getRetrieveMethodName()."(";
$co = 0;
foreach ($table->getPrimaryKey() as $col) {
$clo = strtolower($col->getName());
$script .= ($co++ ? "," : "") . " $".$clo;
} /* foreach */
$script .= ", \$con = null) {
if (\$con === null) {
\$con = Propel::getConnection(self::DATABASE_NAME);
}
\$criteria = new Criteria();";
foreach ($table->getPrimaryKey() as $col) {
$clo = strtolower($col->getName());
$script .= "
\$criteria->add(".$this->getColumnConstant($col).", $".$clo.");";
}
$script .= "
\$v = ".$this->getPeerClassname()."::doSelect(\$criteria, \$con);
return !empty(\$v) ? \$v[0] : null;
}";
}
/**
* Adds the getTableMap() method which is a convenience method for apps to get DB metadata.
* @param string &$script The script will be modified in this method.
*/
protected function addGetTableMap(&$script)
{
$script .= "
/**
* Returns the TableMap related to this peer.
* This method is not needed for general use but a specific application could have a need.
* @return TableMap
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function getTableMap()
{
return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME);
}
";
}
} // PHP5BasicPeerBuilder