(Propel) * @author Leon Messerschmidt (Torque) * @author Jason van Zyl (Torque) * @author Martin Poeschl (Torque) * @author John McNally (Torque) * @author Daniel Rall (Torque) * @author Byron Foster (Torque) * @version $Revision: 1802 $ * @package propel.generator.model */ class Table extends XMLElement implements IDMethod { /** * Enables some debug printing. */ const DEBUG = false; /** * Columns for this table. * * @var array Column[] */ private $columnList = array(); /** * Validators for this table. * * @var array Validator[] */ private $validatorList = array(); /** * Foreign keys for this table. * * @var array ForeignKey[] */ private $foreignKeys = array(); /** * Indexes for this table. * * @var array Index[] */ private $indices = array(); /** * Unique indexes for this table. * * @var array Unique[] */ private $unices = array(); /** * Any parameters for the ID method (currently supports changing sequence name). * * @var array */ private $idMethodParameters = array(); /** * Table name. * * @var string */ private $name; /** * Table description. * * @var string */ private $description; /** * phpName for the table. * * @var string */ private $phpName; /** * Namespace for the generated OM. * * @var string */ protected $namespace; /** * ID method for the table (e.g. IDMethod::NATIVE, IDMethod::NONE). * * @var string */ private $idMethod; /** * Wether an INSERT with set PK is allowed on tables with IDMethod::NATIVE * * @var boolean */ private $allowPkInsert; /** * Strategry to use for converting column name to phpName. * * @var string */ private $phpNamingMethod; /** * The Database that this table belongs to. * * @var Database */ private $database; /** * Foreign Keys that refer to this table. * * @var array ForeignKey[] */ private $referrers = array(); /** * Names of foreign tables. * * @var array string[] */ private $foreignTableNames; /** * Whether this table contains a foreign primary key. * * @var boolean */ private $containsForeignPK; /** * The inheritance column for this table (if any). * * @var Column */ private $inheritanceColumn; /** * Whether to skip generation of SQL for this table. * * @var boolean */ private $skipSql; /** * Whether this table is "read-only". * * @var boolean */ private $readOnly; /** * Whether this table should result in abstract OM classes. * * @var boolean */ private $abstractValue; /** * Whether this table is an alias for another table. * * @var string */ private $alias; /** * The interface that the generated "object" class should implement. * * @var string */ private $enterface; /** * The package for the generated OM. * * @var string */ private $pkg; /** * The base class to extend for the generated "object" class. * * @var string */ private $baseClass; /** * The base peer class to extend for generated "peer" class. * * @var string */ private $basePeer; /** * Map of columns by name. * * @var array */ private $columnsByName = array(); /** * Map of columns by phpName. * * @var array */ private $columnsByPhpName = array(); /** * Whether this table needs to use transactions in Postgres. * * @var string * @deprecated */ private $needsTransactionInPostgres; /** * Whether to perform additional indexing on this table. * * @var boolean */ private $heavyIndexing; /** * Whether this table is for reference only. * * @var boolean */ private $forReferenceOnly; /** * The tree mode (nested set, etc.) implemented by this table. * * @var string */ private $treeMode; /** * Whether to reload the rows in this table after insert. * * @var boolean */ private $reloadOnInsert; /** * Whether to reload the rows in this table after update. * * @var boolean */ private $reloadOnUpdate; /** * List of behaviors registered for this table * * @var array */ protected $behaviors = array(); /** * Whether this table is a cross-reference table for a many-to-many relationship * * @var boolean */ protected $isCrossRef = false; /** * Constructs a table object with a name * * @param string $name table name */ public function __construct($name = null) { $this->name = $name; } /** * Sets up the Rule object based on the attributes that were passed to loadFromXML(). * @see parent::loadFromXML() */ public function setupObject() { $this->name = $this->getDatabase()->getTablePrefix() . $this->getAttribute("name"); // retrieves the method for converting from specified name to a PHP name. $this->phpNamingMethod = $this->getAttribute("phpNamingMethod", $this->getDatabase()->getDefaultPhpNamingMethod()); $this->phpName = $this->getAttribute("phpName", $this->buildPhpName($this->getAttribute('name'))); $namespace = $this->getAttribute("namespace", ''); $package = $this->getAttribute("package"); if ($namespace && !$package && $this->getDatabase()->getBuildProperty('namespaceAutoPackage')) { $package = str_replace('\\', '.', $namespace); } $this->namespace = $namespace; $this->pkg = $package; $this->namespace = $this->getAttribute("namespace"); $this->idMethod = $this->getAttribute("idMethod", $this->getDatabase()->getDefaultIdMethod()); $this->allowPkInsert = $this->booleanValue($this->getAttribute("allowPkInsert")); $this->skipSql = $this->booleanValue($this->getAttribute("skipSql")); $this->readOnly = $this->booleanValue($this->getAttribute("readOnly")); $this->abstractValue = $this->booleanValue($this->getAttribute("abstract")); $this->baseClass = $this->getAttribute("baseClass"); $this->basePeer = $this->getAttribute("basePeer"); $this->alias = $this->getAttribute("alias"); $this->heavyIndexing = ( $this->booleanValue($this->getAttribute("heavyIndexing")) || ("false" !== $this->getAttribute("heavyIndexing") && $this->getDatabase()->isHeavyIndexing() ) ); $this->description = $this->getAttribute("description"); $this->enterface = $this->getAttribute("interface"); // sic ('interface' is reserved word) $this->treeMode = $this->getAttribute("treeMode"); $this->reloadOnInsert = $this->booleanValue($this->getAttribute("reloadOnInsert")); $this->reloadOnUpdate = $this->booleanValue($this->getAttribute("reloadOnUpdate")); $this->isCrossRef = $this->getAttribute("isCrossRef", false); } /** *

A hook for the SAX XML parser to call when this table has * been fully loaded from the XML, and all nested elements have * been processed.

* *

Performs heavy indexing and naming of elements which weren't * provided with a name.

*/ public function doFinalInitialization() { // Heavy indexing must wait until after all columns composing // a table's primary key have been parsed. if ($this->heavyIndexing) { $this->doHeavyIndexing(); } // Name any indices which are missing a name using the // appropriate algorithm. $this->doNaming(); // execute behavior table modifiers foreach ($this->getBehaviors() as $behavior) { if (!$behavior->isTableModified()) { $behavior->getTableModifier()->modifyTable(); $behavior->setTableModified(true); } } // if idMethod is "native" and in fact there are no autoIncrement // columns in the table, then change it to "none" $anyAutoInc = false; foreach ($this->getColumns() as $col) { if ($col->isAutoIncrement()) { $anyAutoInc = true; } } if ($this->getIdMethod() === IDMethod::NATIVE && !$anyAutoInc) { $this->setIdMethod(IDMethod::NO_ID_METHOD); } // If there is no PK, then throw an error. Propel 1.3 requires primary keys. $pk = $this->getPrimaryKey(); if (empty($pk)) { throw new EngineException("Table '".$this->getName()."' does not have a primary key defined. Propel requires all tables to have a primary key."); } } /** *

Adds extra indices for multi-part primary key columns.

* *

For databases like MySQL, values in a where clause much * match key part order from the left to right. So, in the key * definition PRIMARY KEY (FOO_ID, BAR_ID), * FOO_ID must be the first element used in * the where clause of the SQL query used against * this table for the primary key index to be used. This feature * could cause problems under MySQL with heavily indexed tables, * as MySQL currently only supports 16 indices per table (i.e. it * might cause too many indices to be created).

* *

See the * manual for a better description of why heavy indexing is * useful for quickly searchable database tables.

*/ private function doHeavyIndexing() { if (self::DEBUG) { print("doHeavyIndex() called on table " . $this->name."\n"); } $pk = $this->getPrimaryKey(); $size = count($pk); // We start at an offset of 1 because the entire column // list is generally implicitly indexed by the fact that // it's a primary key. for ($i=1; $i < $size; $i++) { $idx = new Index(); $idx->setColumns(array_slice($pk, $i, $size)); $this->addIndex($idx); } } /** * Names composing objects which haven't yet been named. This * currently consists of foreign-key and index entities. */ public function doNaming() { // Assure names are unique across all databases. try { for ($i=0, $size = count($this->foreignKeys); $i < $size; $i++) { $fk = $this->foreignKeys[$i]; $name = $fk->getName(); if (empty($name)) { $name = $this->acquireConstraintName("FK", $i + 1); $fk->setName($name); } } for ($i = 0, $size = count($this->indices); $i < $size; $i++) { $index = $this->indices[$i]; $name = $index->getName(); if (empty($name)) { $name = $this->acquireConstraintName("I", $i + 1); $index->setName($name); } } for ($i = 0, $size = count($this->unices); $i < $size; $i++) { $index = $this->unices[$i]; $name = $index->getName(); if (empty($name)) { $name = $this->acquireConstraintName("U", $i + 1); $index->setName($name); } } // NOTE: Most RDBMSes can apparently name unique column // constraints/indices themselves (using MySQL and Oracle // as test cases), so we'll assume that we needn't add an // entry to the system name list for these. } catch (EngineException $nameAlreadyInUse) { print $nameAlreadyInUse->getMessage() . "\n"; print $nameAlreadyInUse->getTraceAsString(); } } /** * Macro to a constraint name. * * @param nameType constraint type * @param nbr unique number for this constraint type * @return unique name for constraint * @throws EngineException */ private function acquireConstraintName($nameType, $nbr) { $inputs = array(); $inputs[] = $this->getDatabase(); $inputs[] = $this->getName(); $inputs[] = $nameType; $inputs[] = $nbr; return NameFactory::generateName(NameFactory::CONSTRAINT_GENERATOR, $inputs); } /** * Gets the value of base class for classes produced from this table. * * @return The base class for classes produced from this table. */ public function getBaseClass() { if ($this->isAlias() && $this->baseClass === null) { return $this->alias; } elseif ($this->baseClass === null) { return $this->getDatabase()->getBaseClass(); } else { return $this->baseClass; } } /** * Set the value of baseClass. * @param v Value to assign to baseClass. */ public function setBaseClass($v) { $this->baseClass = $v; } /** * Get the value of basePeer. * @return value of basePeer. */ public function getBasePeer() { if ($this->isAlias() && $this->basePeer === null) { return $this->alias . "Peer"; } elseif ($this->basePeer === null) { return $this->getDatabase()->getBasePeer(); } else { return $this->basePeer; } } /** * Set the value of basePeer. * @param v Value to assign to basePeer. */ public function setBasePeer($v) { $this->basePeer = $v; } /** * A utility function to create a new column from attrib and add it to this * table. * * @param $coldata xml attributes or Column class for the column to add * @return the added column */ public function addColumn($data) { if ($data instanceof Column) { $col = $data; $col->setTable($this); if ($col->isInheritance()) { $this->inheritanceColumn = $col; } if (isset($this->columnsByName[$col->getName()])) { throw new EngineException('Duplicate column declared: ' . $col->getName()); } $this->columnList[] = $col; $this->columnsByName[$col->getName()] = $col; $this->columnsByPhpName[$col->getPhpName()] = $col; $col->setPosition(count($this->columnList)); $this->needsTransactionInPostgres |= $col->requiresTransactionInPostgres(); return $col; } else { $col = new Column(); $col->setTable($this); $col->loadFromXML($data); return $this->addColumn($col); // call self w/ different param } } /** * Add a validator to this table. * * Supports two signatures: * - addValidator(Validator $validator) * - addValidator(array $attribs) * * @param mixed $data Validator object or XML attribs (array) from element. * @return Validator The added Validator. * @throws EngineException */ public function addValidator($data) { if ($data instanceof Validator) { $validator = $data; $col = $this->getColumn($validator->getColumnName()); if ($col == null) { throw new EngineException("Failed adding validator to table '" . $this->getName() . "': column '" . $validator->getColumnName() . "' does not exist !"); } $validator->setColumn($col); $validator->setTable($this); $this->validatorList[] = $validator; return $validator; } else { $validator = new Validator(); $validator->setTable($this); $validator->loadFromXML($data); return $this->addValidator($validator); } } /** * A utility function to create a new foreign key * from attrib and add it to this table. */ public function addForeignKey($fkdata) { if ($fkdata instanceof ForeignKey) { $fk = $fkdata; $fk->setTable($this); $this->foreignKeys[] = $fk; if ($this->foreignTableNames === null) { $this->foreignTableNames = array(); } if (!in_array($fk->getForeignTableName(), $this->foreignTableNames)) { $this->foreignTableNames[] = $fk->getForeignTableName(); } return $fk; } else { $fk = new ForeignKey(); $fk->setTable($this); $fk->loadFromXML($fkdata); return $this->addForeignKey($fk); } } /** * Gets the column that subclasses of the class representing this * table can be produced from. * @return Column */ public function getChildrenColumn() { return $this->inheritanceColumn; } /** * Get the subclasses that can be created from this table. * @return array string[] Class names */ public function getChildrenNames() { if ($this->inheritanceColumn === null || !$this->inheritanceColumn->isEnumeratedClasses()) { return null; } $children = $this->inheritanceColumn->getChildren(); $names = array(); for ($i = 0, $size=count($children); $i < $size; $i++) { $names[] = get_class($children[$i]); } return $names; } /** * Adds the foreign key from another table that refers to this table. */ public function addReferrer(ForeignKey $fk) { if ($this->referrers === null) { $this->referrers = array(); } $this->referrers[] = $fk; } /** * Get list of references to this table. */ public function getReferrers() { return $this->referrers; } public function getCrossFks() { $crossFks = array(); foreach ($this->getReferrers() as $refFK) { if ($refFK->getTable()->getIsCrossRef()) { foreach ($refFK->getOtherFks() as $crossFK) { $crossFks[]= array($refFK, $crossFK); } } } return $crossFks; } /** * Set whether this table contains a foreign PK */ public function setContainsForeignPK($b) { $this->containsForeignPK = (boolean) $b; } /** * Determine if this table contains a foreign PK */ public function getContainsForeignPK() { return $this->containsForeignPK; } /** * A list of tables referenced by foreign keys in this table */ public function getForeignTableNames() { if ($this->foreignTableNames === null) { $this->foreignTableNames = array(); } return $this->foreignTableNames; } /** * Return true if the column requires a transaction in Postgres */ public function requiresTransactionInPostgres() { return $this->needsTransactionInPostgres; } /** * A utility function to create a new id method parameter * from attrib or object and add it to this table. */ public function addIdMethodParameter($impdata) { if ($impdata instanceof IdMethodParameter) { $imp = $impdata; $imp->setTable($this); if ($this->idMethodParameters === null) { $this->idMethodParameters = array(); } $this->idMethodParameters[] = $imp; return $imp; } else { $imp = new IdMethodParameter(); $imp->loadFromXML($impdata); return $this->addIdMethodParameter($imp); // call self w/ diff param } } /** * Adds a new index to the index list and set the * parent table of the column to the current table */ public function addIndex($idxdata) { if ($idxdata instanceof Index) { $index = $idxdata; $index->setTable($this); $index->getName(); // we call this method so that the name is created now if it doesn't already exist. $this->indices[] = $index; return $index; } else { $index = new Index($this); $index->loadFromXML($idxdata); return $this->addIndex($index); } } /** * Adds a new Unique to the Unique list and set the * parent table of the column to the current table */ public function addUnique($unqdata) { if ($unqdata instanceof Unique) { $unique = $unqdata; $unique->setTable($this); $unique->getName(); // we call this method so that the name is created now if it doesn't already exist. $this->unices[] = $unique; return $unique; } else { $unique = new Unique($this); $unique->loadFromXML($unqdata); return $this->addUnique($unique); } } /** * Retrieves the configuration object, filled by build.properties * * @return GeneratorConfig */ public function getGeneratorConfig() { return $this->getDatabase()->getAppData()->getPlatform()->getGeneratorConfig(); } /** * Adds a new Behavior to the table * @return Behavior A behavior instance */ public function addBehavior($bdata) { if ($bdata instanceof Behavior) { $behavior = $bdata; $behavior->setTable($this); $this->behaviors[$behavior->getName()] = $behavior; return $behavior; } else { $class = $this->getConfiguredBehavior($bdata['name']); $behavior = new $class(); $behavior->loadFromXML($bdata); return $this->addBehavior($behavior); } } /** * Get the table behaviors * @return Array of Behavior objects */ public function getBehaviors() { return $this->behaviors; } /** * Get the early table behaviors * @return Array of Behavior objects */ public function getEarlyBehaviors() { $behaviors = array(); foreach ($this->behaviors as $name => $behavior) { if ($behavior->isEarly()) { $behaviors[$name] = $behavior; } } return $behaviors; } /** * check if the table has a behavior by name * * @param string $name the behavior name * @return boolean True if the behavior exists */ public function hasBehavior($name) { return array_key_exists($name, $this->behaviors); } /** * Get one table behavior by name * * @param string $name the behavior name * @return Behavior a behavior object */ public function getBehavior($name) { return $this->behaviors[$name]; } /** * Get the name of the Table */ public function getName() { return $this->name; } /** * Set the name of the Table */ public function setName($newName) { $this->name = $newName; } /** * Get the description for the Table */ public function getDescription() { return $this->description; } /** * Set the description for the Table * * @param newDescription description for the Table */ public function setDescription($newDescription) { $this->description = $newDescription; } /** * Get name to use in PHP sources * @return string */ public function getPhpName() { if ($this->phpName === null) { $inputs = array(); $inputs[] = $this->name; $inputs[] = $this->phpNamingMethod; try { $this->phpName = NameFactory::generateName(NameFactory::PHP_GENERATOR, $inputs); } catch (EngineException $e) { print $e->getMessage() . "\n"; print $e->getTraceAsString(); } } return $this->phpName; } /** * Set name to use in PHP sources * @param string $phpName */ public function setPhpName($phpName) { $this->phpName = $phpName; } public function buildPhpName($name) { return NameFactory::generateName(NameFactory::PHP_GENERATOR, array($name, $this->phpNamingMethod)); } /** * Get studly version of PHP name. * * The studly name is the PHP name with the first character lowercase. * * @return string */ public function getStudlyPhpName() { $phpname = $this->getPhpName(); if (strlen($phpname) > 1) { return strtolower(substr($phpname, 0, 1)) . substr($phpname, 1); } else { // 0 or 1 chars (I suppose that's rare) return strtolower($phpname); } } /** * Get the value of the namespace. * @return value of namespace. */ public function getNamespace() { if (strpos($this->namespace, '\\') === 0) { // absolute table namespace return substr($this->namespace, 1); } elseif ($this->namespace && $this->getDatabase() && $this->getDatabase()->getNamespace()) { return $this->getDatabase()->getNamespace() . '\\' . $this->namespace; } elseif ($this->getDatabase() && $this->getDatabase()->getNamespace()) { return $this->getDatabase()->getNamespace(); } else { return $this->namespace; } } /** * Set the value of the namespace. * @param v Value to assign to namespace. */ public function setNamespace($v) { $this->namespace = $v; } /** * Get the method for generating pk's * [HL] changing behavior so that Database default method is returned * if no method has been specified for the table. * * @return string */ public function getIdMethod() { if ($this->idMethod === null) { return IDMethod::NO_ID_METHOD; } else { return $this->idMethod; } } /** * Whether we allow to insert primary keys on tables with * idMethod=native * * @return boolean */ public function isAllowPkInsert() { return $this->allowPkInsert; } /** * Set the method for generating pk's */ public function setIdMethod($idMethod) { $this->idMethod = $idMethod; } /** * Skip generating sql for this table (in the event it should * not be created from scratch). * @return boolean Value of skipSql. */ public function isSkipSql() { return ($this->skipSql || $this->isAlias() || $this->isForReferenceOnly()); } /** * Is table read-only, in which case only accessors (and relationship setters) * will be created. * @return boolan Value of readOnly. */ public function isReadOnly() { return $this->readOnly; } /** * Set whether this table should have its creation sql generated. * @param boolean $v Value to assign to skipSql. */ public function setSkipSql($v) { $this->skipSql = $v; } /** * Whether to force object to reload on INSERT. * @return boolean */ public function isReloadOnInsert() { return $this->reloadOnInsert; } /** * Whether to force object to reload on UPDATE. * @return boolean */ public function isReloadOnUpdate() { return $this->reloadOnUpdate; } /** * PhpName of om object this entry references. * @return value of external. */ public function getAlias() { return $this->alias; } /** * Is this table specified in the schema or is there just * a foreign key reference to it. * @return value of external. */ public function isAlias() { return ($this->alias !== null); } /** * Set whether this table specified in the schema or is there just * a foreign key reference to it. * @param v Value to assign to alias. */ public function setAlias($v) { $this->alias = $v; } /** * Interface which objects for this table will implement * @return value of interface. */ public function getInterface() { return $this->enterface; } /** * Interface which objects for this table will implement * @param v Value to assign to interface. */ public function setInterface($v) { $this->enterface = $v; } /** * When a table is abstract, it marks the business object class that is * generated as being abstract. If you have a table called "FOO", then the * Foo BO will be public abstract class Foo * This helps support class hierarchies * * @return value of abstractValue. */ public function isAbstract() { return $this->abstractValue; } /** * When a table is abstract, it marks the business object * class that is generated as being abstract. If you have a * table called "FOO", then the Foo BO will be * public abstract class Foo * This helps support class hierarchies * * @param v Value to assign to abstractValue. */ public function setAbstract($v) { $this->abstractValue = (boolean) $v; } /** * Get the value of package. * @return value of package. */ public function getPackage() { return $this->pkg; } /** * Set the value of package. * @param v Value to assign to package. */ public function setPackage($v) { $this->pkg = $v; } /** * Returns an Array containing all the columns in the table * @return array Column[] */ public function getColumns() { return $this->columnList; } /** * Utility method to get the number of columns in this table */ public function getNumColumns() { return count($this->columnList); } /** * Utility method to get the number of columns in this table */ public function getNumLazyLoadColumns() { $count = 0; foreach ($this->columnList as $col) { if ($col->isLazyLoad()) { $count++; } } return $count; } /** * Returns an Array containing all the validators in the table * @return array Validator[] */ public function getValidators() { return $this->validatorList; } /** * Returns an Array containing all the FKs in the table. * @return array ForeignKey[] */ public function getForeignKeys() { return $this->foreignKeys; } /** * Returns a Collection of parameters relevant for the chosen * id generation method. */ public function getIdMethodParameters() { return $this->idMethodParameters; } /** * Returns an Array containing all the FKs in the table * @return array Index[] */ public function getIndices() { return $this->indices; } /** * Returns an Array containing all the UKs in the table * @return array Unique[] */ public function getUnices() { return $this->unices; } /** * Check whether the table has a column. * @return boolean */ public function hasColumn($name) { return array_key_exists($name, $this->columnsByName); } /** * Returns a specified column. * @return Column Return a Column object or null if it does not exist. */ public function getColumn($name) { return @$this->columnsByName[$name]; } /** * Returns a specified column. * @return Column Return a Column object or null if it does not exist. */ public function getColumnByPhpName($phpName) { return @$this->columnsByPhpName[$phpName]; } /** * Get all the foreign keys from this table to the specified table. * @return array ForeignKey[] */ public function getForeignKeysReferencingTable($tablename) { $matches = array(); $keys = $this->getForeignKeys(); foreach ($keys as $fk) { if ($fk->getForeignTableName() === $tablename) { $matches[] = $fk; } } return $matches; } /** * Return the foreign keys that includes col in it's list of local columns. * Eg. Foreign key (a,b,c) refrences tbl(x,y,z) will be returned of col is either a,b or c. * @param string $col * @return array ForeignKey[] or null if there is no FK for specified column. */ public function getColumnForeignKeys($colname) { $matches = array(); foreach ($this->foreignKeys as $fk) { if (in_array($colname, $fk->getLocalColumns())) { $matches[] = $fk; } } return $matches; } /** * Returns true if the table contains a specified column * @param mixed $col Column or column name. */ public function containsColumn($col) { if ($col instanceof Column) { return in_array($col, $this->columnList); } else { return ($this->getColumn($col) !== null); } } /** * Set the database that contains this table. * * @param Database $db */ public function setDatabase(Database $db) { $this->database = $db; } /** * Get the database that contains this table. * * @return Database */ public function getDatabase() { return $this->database; } /** * Flag to determine if code/sql gets created for this table. * Table will be skipped, if return true. * @return boolean */ public function isForReferenceOnly() { return $this->forReferenceOnly; } /** * Flag to determine if code/sql gets created for this table. * Table will be skipped, if set to true. * @param boolean $v */ public function setForReferenceOnly($v) { $this->forReferenceOnly = (boolean) $v; } /** * Flag to determine if tree node class should be generated for this table. * @return valur of treeMode */ public function treeMode() { return $this->treeMode; } /** * Flag to determine if tree node class should be generated for this table. * @param v Value to assign to treeMode. */ public function setTreeMode($v) { $this->treeMode = $v; } /** * Appends XML nodes to passed-in DOMNode. * * @param DOMNode $node */ public function appendXml(DOMNode $node) { $doc = ($node instanceof DOMDocument) ? $node : $node->ownerDocument; $tableNode = $node->appendChild($doc->createElement('table')); $tableNode->setAttribute('name', $this->getName()); if ($this->phpName !== null) { $tableNode->setAttribute('phpName', $this->phpName); } if ($this->idMethod !== null) { $tableNode->setAttribute('idMethod', $this->idMethod); } if ($this->skipSql !== null) { $tableNode->setAttribute('idMethod', var_export($this->skipSql, true)); } if ($this->readOnly !== null) { $tableNode->setAttribute('readOnly', var_export($this->readOnly, true)); } if ($this->treeMode !== null) { $tableNode->setAttribute('treeMode', $this->treeMode); } if ($this->reloadOnInsert !== null) { $tableNode->setAttribute('reloadOnInsert', var_export($this->reloadOnInsert, true)); } if ($this->reloadOnUpdate !== null) { $tableNode->setAttribute('reloadOnUpdate', var_export($this->reloadOnUpdate, true)); } if ($this->forReferenceOnly !== null) { $tableNode->setAttribute('forReferenceOnly', var_export($this->forReferenceOnly, true)); } if ($this->abstractValue !== null) { $tableNode->setAttribute('abstract', var_export($this->abstractValue, true)); } if ($this->enterface !== null) { $tableNode->setAttribute('interface', $this->enterface); } if ($this->description !== null) { $tableNode->setAttribute('description', $this->description); } if ($this->baseClass !== null) { $tableNode->setAttribute('baseClass', $this->baseClass); } if ($this->basePeer !== null) { $tableNode->setAttribute('basePeer', $this->basePeer); } if ($this->getIsCrossRef()) { $tableNode->setAttribute('isCrossRef', $this->getIsCrossRef()); } foreach ($this->columnList as $col) { $col->appendXml($tableNode); } foreach ($this->validatorList as $validator) { $validator->appendXml($tableNode); } foreach ($this->foreignKeys as $fk) { $fk->appendXml($tableNode); } foreach ($this->idMethodParameters as $param) { $param->appendXml($tableNode); } foreach ($this->indices as $index) { $index->appendXml($tableNode); } foreach ($this->unices as $unique) { $unique->appendXml($tableNode); } foreach ($this->vendorInfos as $vi) { $vi->appendXml($tableNode); } } /** * Returns the collection of Columns which make up the single primary * key for this table. * * @return array Column[] A list of the primary key parts. */ public function getPrimaryKey() { $pk = array(); foreach ($this->columnList as $col) { if ($col->isPrimaryKey()) { $pk[] = $col; } } return $pk; } /** * Determine whether this table has a primary key. * * @return boolean Whether this table has any primary key parts. */ public function hasPrimaryKey() { return (count($this->getPrimaryKey()) > 0); } /** * Determine whether this table has a composite primary key. * * @return boolean Whether this table has more than one primary key parts. */ public function hasCompositePrimaryKey() { return (count($this->getPrimaryKey()) > 1); } /** * Determine whether this table has any auto-increment primary key(s). * * @return boolean Whether this table has a non-"none" id method and has a primary key column that is auto-increment. */ public function hasAutoIncrementPrimaryKey() { if ($this->getIdMethod() != IDMethod::NO_ID_METHOD) { $pks =$this->getPrimaryKey(); foreach ($pks as $pk) { if ($pk->isAutoIncrement()) { return true; } } } return false; } /** * Gets the auto increment PK * * @return Column if any auto increment PK column */ public function getAutoIncrementPrimaryKey() { if ($this->getIdMethod() != IDMethod::NO_ID_METHOD) { $pks =$this->getPrimaryKey(); foreach ($pks as $pk) { if ($pk->isAutoIncrement()) { return $pk; } } } return null; } /** * Returns all parts of the primary key, separated by commas. * * @return A CSV list of primary key parts. * @deprecated Use the DDLBuilder->getColumnList() with the #getPrimaryKey() method. */ public function printPrimaryKey() { return $this->printList($this->columnList); } /** * Gets the crossRef status for this foreign key * @return boolean */ public function getIsCrossRef() { return $this->isCrossRef; } /** * Sets a crossref status for this foreign key. * @param boolean $isCrossRef */ public function setIsCrossRef($isCrossRef) { $this->isCrossRef = (bool) $isCrossRef; } /** * Returns the elements of the list, separated by commas. * @param array $list * @return A CSV list. * @deprecated Use the DDLBuilder->getColumnList() with the #getPrimaryKey() method. */ private function printList($list){ $result = ""; $comma = 0; for ($i=0,$_i=count($list); $i < $_i; $i++) { $col = $list[$i]; if ($col->isPrimaryKey()) { $result .= ($comma++ ? ',' : '') . $this->getDatabase()->getPlatform()->quoteIdentifier($col->getName()); } } return $result; } }