1
0
mirror of synced 2025-02-21 14:43:14 +03:00

Implemented generation of indexes and their definitions from schema files.

This commit is contained in:
phuson 2007-10-14 06:44:49 +00:00
parent 4805dab42b
commit a98961bd03
2 changed files with 435 additions and 374 deletions

View File

@ -1,367 +1,421 @@
<?php <?php
/* /*
* $Id$ * $Id$
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* This software consists of voluntary contributions made by many individuals * This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see * and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.com>. * <http://www.phpdoctrine.com>.
*/ */
/** /**
* Doctrine_Import_Builder * Doctrine_Import_Builder
* Import builder is responsible of building Doctrine ActiveRecord classes * Import builder is responsible of building Doctrine ActiveRecord classes
* based on a database schema. * based on a database schema.
* *
* @package Doctrine * @package Doctrine
* @subpackage Import * @subpackage Import
* @link www.phpdoctrine.com * @link www.phpdoctrine.com
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @since 1.0 * @since 1.0
* @version $Revision$ * @version $Revision$
* @author Konsta Vesterinen <kvesteri@cc.hut.fi> * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @author Jukka Hassinen <Jukka.Hassinen@BrainAlliance.com> * @author Jukka Hassinen <Jukka.Hassinen@BrainAlliance.com>
* @author Nicolas Bérard-Nault <nicobn@php.net> * @author Nicolas Bérard-Nault <nicobn@php.net>
*/ */
class Doctrine_Import_Builder class Doctrine_Import_Builder
{ {
/** /**
* @var string $path the path where imported files are being generated * @var string $path the path where imported files are being generated
*/ */
private $path = ''; private $path = '';
private $suffix = '.class.php'; private $suffix = '.class.php';
private $generateBaseClasses = false; private $generateBaseClasses = false;
private $baseClassesDirectory = 'generated'; private $baseClassesDirectory = 'generated';
private static $tpl; private static $tpl;
public function __construct() public function __construct()
{ {
$this->loadTemplate(); $this->loadTemplate();
} }
/** /**
* setTargetPath * setTargetPath
* *
* @param string path the path where imported files are being generated * @param string path the path where imported files are being generated
* @return * @return
*/ */
public function setTargetPath($path) public function setTargetPath($path)
{ {
if ( ! file_exists($path)) { if ( ! file_exists($path)) {
mkdir($path, 0777); mkdir($path, 0777);
} }
$this->path = $path; $this->path = $path;
} }
/** /**
* generateBaseClasses * generateBaseClasses
* *
* Specify whether or not to generate classes which extend from generated base classes * Specify whether or not to generate classes which extend from generated base classes
* *
* @param string $bool * @param string $bool
* @return void * @return void
* @author Jonathan H. Wage * @author Jonathan H. Wage
*/ */
public function generateBaseClasses($bool = null) public function generateBaseClasses($bool = null)
{ {
if ($bool !== null) { if ($bool !== null) {
$this->generateBaseClasses = $bool; $this->generateBaseClasses = $bool;
} }
return $this->generateBaseClasses; return $this->generateBaseClasses;
} }
/** /**
* getTargetPath * getTargetPath
* *
* @return string the path where imported files are being generated * @return string the path where imported files are being generated
*/ */
public function getTargetPath() public function getTargetPath()
{ {
return $this->path; return $this->path;
} }
/** /**
* This is a template that was previously in Builder/Record.tpl. Due to the fact * This is a template that was previously in Builder/Record.tpl. Due to the fact
* that it was not bundled when compiling, it had to be moved here. * that it was not bundled when compiling, it had to be moved here.
* *
* @return void * @return void
*/ */
public function loadTemplate() public function loadTemplate()
{ {
if (isset(self::$tpl)) { if (isset(self::$tpl)) {
return; return;
} }
self::$tpl =<<<END self::$tpl =<<<END
/** /**
* This class has been auto-generated by the Doctrine ORM Framework * This class has been auto-generated by the Doctrine ORM Framework
*/ */
%sclass %s extends %s %sclass %s extends %s
{ {
%s %s
%s %s
} }
END; END;
} }
/* /*
* Build the table definition of a Doctrine_Record object * Build the table definition of a Doctrine_Record object
* *
* @param string $table * @param string $table
* @param array $tableColumns * @param array $tableColumns
*/ */
public function buildTableDefinition(array $options, array $columns, array $relations) public function buildTableDefinition(array $options, array $columns, array $relations, array $indexes)
{ {
$ret = array(); $ret = array();
$i = 0; $i = 0;
if (isset($options['inheritance']['extends']) && !isset($options['override_parent'])) { if (isset($options['inheritance']['extends']) && !isset($options['override_parent'])) {
$ret[$i] = "\t\t\t\tparent::setTableDefinition();"; $ret[$i] = "\t\t\t\tparent::setTableDefinition();";
$i++; $i++;
} }
if (isset($options['tableName']) && !empty($options['tableName'])) { if (isset($options['tableName']) && !empty($options['tableName'])) {
$ret[$i] = str_repeat(' ', 8) . '$this->setTableName(\''. $options['tableName'].'\');'; $ret[$i] = str_repeat(' ', 8) . '$this->setTableName(\''. $options['tableName'].'\');';
$i++; $i++;
} }
foreach ($columns as $name => $column) { foreach ($columns as $name => $column) {
$ret[$i] = ' $this->hasColumn(\'' . $name . '\', \'' . $column['type'] . '\''; $ret[$i] = ' $this->hasColumn(\'' . $name . '\', \'' . $column['type'] . '\'';
if ($column['length']) { if ($column['length']) {
$ret[$i] .= ', ' . $column['length']; $ret[$i] .= ', ' . $column['length'];
} else { } else {
$ret[$i] .= ', null'; $ret[$i] .= ', null';
} }
$a = array(); $a = array();
if (isset($column['default']) && $column['default']) { if (isset($column['default']) && $column['default']) {
$a[] = '\'default\' => ' . var_export($column['default'], true); $a[] = '\'default\' => ' . var_export($column['default'], true);
} }
if (isset($column['notnull']) && $column['notnull']) { if (isset($column['notnull']) && $column['notnull']) {
$a[] = '\'notnull\' => true'; $a[] = '\'notnull\' => true';
} }
if (isset($column['primary']) && $column['primary']) { if (isset($column['primary']) && $column['primary']) {
$a[] = '\'primary\' => true'; $a[] = '\'primary\' => true';
} }
if ((isset($column['autoinc']) && $column['autoinc']) || isset($column['autoincrement']) && $column['autoincrement']) { if ((isset($column['autoinc']) && $column['autoinc']) || isset($column['autoincrement']) && $column['autoincrement']) {
$a[] = '\'autoincrement\' => true'; $a[] = '\'autoincrement\' => true';
} }
if (isset($column['unique']) && $column['unique']) { if (isset($column['unique']) && $column['unique']) {
$a[] = '\'unique\' => true'; $a[] = '\'unique\' => true';
} }
if (isset($column['unsigned']) && $column['unsigned']) { if (isset($column['unsigned']) && $column['unsigned']) {
$a[] = '\'unsigned\' => true'; $a[] = '\'unsigned\' => true';
} }
if ($column['type'] == 'enum' && isset($column['values']) ) { if ($column['type'] == 'enum' && isset($column['values']) ) {
$a[] = '\'values\' => array(\'' . implode('\',\'', $column['values']) . '\')'; $a[] = '\'values\' => array(\'' . implode('\',\'', $column['values']) . '\')';
} }
if ( ! empty($a)) { if ( ! empty($a)) {
$ret[$i] .= ', ' . 'array('; $ret[$i] .= ', ' . 'array(';
$length = strlen($ret[$i]); $length = strlen($ret[$i]);
$ret[$i] .= implode(',' . PHP_EOL . str_repeat(' ', $length), $a) . ')'; $ret[$i] .= implode(',' . PHP_EOL . str_repeat(' ', $length), $a) . ')';
} }
$ret[$i] .= ');'; $ret[$i] .= ');';
if ($i < (count($columns) - 1)) { if ($i < (count($columns) - 1)) {
$ret[$i] .= PHP_EOL; $ret[$i] .= PHP_EOL;
} }
$i++; $i++;
} }
if (!empty($ret)) { foreach ($indexes as $indexName => $definitions) {
return "\n\tpublic function setTableDefinition()"."\n\t{\n".implode("\n", $ret)."\n\t}"; $ret[$i] = "\n".' $this->index(\'' . $indexName . '\', array(';
}
} foreach ($definitions as $name => $value) {
public function buildSetUp(array $options, array $columns, array $relations)
{ // parse fields
$ret = array(); if ($name === 'fields') {
$ret[$i] .= '\'fields\' => array(';
$i = 0;
foreach ($value as $fieldName => $fieldValue) {
if (isset($options['inheritance']['extends']) && !isset($options['override_parent'])) { $ret[$i] .= '\'' . $fieldName . '\' => array( ';
$ret[$i] = "\t\t\t\tparent::setUp();";
$i++; // parse options { sorting, length, primary }
} if (isset($fieldValue) && $fieldValue) {
foreach ($fieldValue as $optionName => $optionValue) {
foreach ($relations as $name => $relation) {
$class = isset($relation['class']) ? $relation['class']:$name; $ret[$i] .= '\'' . $optionName . '\' => ';
$alias = (isset($relation['alias']) && $relation['alias'] !== $relation['class']) ? ' as ' . $relation['alias'] : '';
// check primary option, mark either as true or false
if ( ! isset($relation['type'])) { if ($optionName === 'primary') {
$relation['type'] = Doctrine_Relation::ONE; $ret[$i] .= (($optionValue == 'true') ? 'true' : 'false') . ', ';
} continue;
}
if ($relation['type'] === Doctrine_Relation::ONE ||
$relation['type'] === Doctrine_Relation::ONE_COMPOSITE) { // convert sorting option to uppercase, for instance, asc -> ASC
$ret[$i] = ' $this->hasOne(\'' . $class . $alias . '\''; if ($optionName === 'sorting') {
} else { $ret[$i] .= '\'' . strtoupper($optionValue) . '\', ';
$ret[$i] = ' $this->hasMany(\'' . $class . $alias . '\''; continue;
} }
$a = array(); // check the rest of the options
$ret[$i] .= '\'' . $optionValue . '\', ';
if (isset($relation['refClass'])) { }
$a[] = '\'refClass\' => ' . var_export($relation['refClass'], true); }
}
$ret[$i] .= '), ';
if (isset($relation['deferred']) && $relation['deferred']) { }
$a[] = '\'default\' => ' . var_export($relation['deferred'], true); }
}
// parse index type option, 4 choices { unique, fulltext, gist, gin }
if (isset($relation['local']) && $relation['local']) { if ($name === 'type') {
$a[] = '\'local\' => ' . var_export($relation['local'], true); $ret[$i] .= '), \'type\' => \'' . $value . '\'';
} }
if (isset($relation['foreign']) && $relation['foreign']) { // add extra ) if type definition is not declared
$a[] = '\'foreign\' => ' . var_export($relation['foreign'], true); if (!isset($definitions['type'])) {
} $ret[$i] .= ')';
}
if (isset($relation['onDelete']) && $relation['onDelete']) { }
$a[] = '\'onDelete\' => ' . var_export($relation['onDelete'], true);
} $ret[$i] .= '));';
$i++;
if (isset($relation['onUpdate']) && $relation['onUpdate']) { }
$a[] = '\'onUpdate\' => ' . var_export($relation['onUpdate'], true);
} if (!empty($ret)) {
return "\n\tpublic function setTableDefinition()"."\n\t{\n".implode("\n", $ret)."\n\t}";
if ( ! empty($a)) { }
$ret[$i] .= ', ' . 'array('; }
$length = strlen($ret[$i]); public function buildSetUp(array $options, array $columns, array $relations)
$ret[$i] .= implode(',' . PHP_EOL . str_repeat(' ', $length), $a) . ')'; {
} $ret = array();
$ret[$i] .= ');'; $i = 0;
$i++;
} if (isset($options['inheritance']['extends']) && !isset($options['override_parent'])) {
$ret[$i] = "\t\t\t\tparent::setUp();";
if (isset($options['inheritance']['keyField']) && isset($options['inheritance']['keyValue'])) { $i++;
$i++; }
$ret[$i] = "\t\t".'$this->setInheritanceMap(array(\''.$options['inheritance']['keyField'].'\' => '.$options['inheritance']['keyValue'].'));';
} foreach ($relations as $name => $relation) {
$class = isset($relation['class']) ? $relation['class']:$name;
if (!empty($ret)) { $alias = (isset($relation['alias']) && $relation['alias'] !== $relation['class']) ? ' as ' . $relation['alias'] : '';
return "\n\tpublic function setUp()\n\t{\n".implode("\n", $ret)."\n\t}";
} if ( ! isset($relation['type'])) {
} $relation['type'] = Doctrine_Relation::ONE;
}
public function buildDefinition(array $options, array $columns, array $relations = array())
{ if ($relation['type'] === Doctrine_Relation::ONE ||
if ( ! isset($options['className'])) { $relation['type'] === Doctrine_Relation::ONE_COMPOSITE) {
throw new Doctrine_Import_Builder_Exception('Missing class name.'); $ret[$i] = ' $this->hasOne(\'' . $class . $alias . '\'';
} } else {
$ret[$i] = ' $this->hasMany(\'' . $class . $alias . '\'';
$abstract = isset($options['abstract']) ? 'abstract ':null; }
$className = $options['className'];
$extends = isset($options['inheritance']['extends']) ? $options['inheritance']['extends']:'Doctrine_Record'; $a = array();
$definition = !isset($options['no_definition']) ? $this->buildTableDefinition($options, $columns, $relations):null;
$setUp = !isset($options['no_definition']) ? $this->buildSetUp($options, $columns, $relations):null; if (isset($relation['refClass'])) {
$a[] = '\'refClass\' => ' . var_export($relation['refClass'], true);
$content = sprintf(self::$tpl, $abstract, }
$className,
$extends, if (isset($relation['deferred']) && $relation['deferred']) {
$definition, $a[] = '\'default\' => ' . var_export($relation['deferred'], true);
$setUp); }
return $content; if (isset($relation['local']) && $relation['local']) {
} $a[] = '\'local\' => ' . var_export($relation['local'], true);
}
public function buildRecord(array $options, array $columns, array $relations = array())
{ if (isset($relation['foreign']) && $relation['foreign']) {
if ( !isset($options['className'])) { $a[] = '\'foreign\' => ' . var_export($relation['foreign'], true);
throw new Doctrine_Import_Builder_Exception('Missing class name.'); }
}
if (isset($relation['onDelete']) && $relation['onDelete']) {
if ( !isset($options['fileName'])) { $a[] = '\'onDelete\' => ' . var_export($relation['onDelete'], true);
if (empty($this->path)) { }
throw new Doctrine_Import_Builder_Exception('No build target directory set.');
} if (isset($relation['onUpdate']) && $relation['onUpdate']) {
$a[] = '\'onUpdate\' => ' . var_export($relation['onUpdate'], true);
}
if (is_writable($this->path) === false) {
throw new Doctrine_Import_Builder_Exception('Build target directory ' . $this->path . ' is not writable.'); if ( ! empty($a)) {
} $ret[$i] .= ', ' . 'array(';
$length = strlen($ret[$i]);
$options['fileName'] = $this->path . DIRECTORY_SEPARATOR . $options['className'] . $this->suffix; $ret[$i] .= implode(',' . PHP_EOL . str_repeat(' ', $length), $a) . ')';
} }
if ($this->generateBaseClasses()) { $ret[$i] .= ');';
$i++;
// We only want to generate this one if it doesn't already exist }
if (!file_exists($options['fileName'])) {
$optionsBak = $options; if (isset($options['inheritance']['keyField']) && isset($options['inheritance']['keyValue'])) {
$i++;
unset($options['tableName']); $ret[$i] = "\t\t".'$this->setInheritanceMap(array(\''.$options['inheritance']['keyField'].'\' => '.$options['inheritance']['keyValue'].'));';
$options['inheritance']['extends'] = 'Base' . $options['className']; }
$options['requires'] = array($this->baseClassesDirectory . DIRECTORY_SEPARATOR . $options['inheritance']['extends'] . $this->suffix);
$options['no_definition'] = true; if (!empty($ret)) {
return "\n\tpublic function setUp()\n\t{\n".implode("\n", $ret)."\n\t}";
$this->writeDefinition($options, array(), array()); }
}
$options = $optionsBak;
} public function buildDefinition(array $options, array $columns, array $relations = array(), array $indexes = array())
{
$generatedPath = $this->path . DIRECTORY_SEPARATOR . $this->baseClassesDirectory; if ( ! isset($options['className'])) {
throw new Doctrine_Import_Builder_Exception('Missing class name.');
if (!file_exists($generatedPath)) { }
mkdir($generatedPath);
} $abstract = isset($options['abstract']) ? 'abstract ':null;
$className = $options['className'];
$options['className'] = 'Base' . $options['className']; $extends = isset($options['inheritance']['extends']) ? $options['inheritance']['extends']:'Doctrine_Record';
$options['abstract'] = true; $definition = !isset($options['no_definition']) ? $this->buildTableDefinition($options, $columns, $relations, $indexes):null;
$options['fileName'] = $generatedPath . DIRECTORY_SEPARATOR . $options['className'] . $this->suffix; $setUp = !isset($options['no_definition']) ? $this->buildSetUp($options, $columns, $relations):null;
$this->writeDefinition($options, $columns, $relations); $content = sprintf(self::$tpl, $abstract,
} else { $className,
$this->writeDefinition($options, $columns, $relations); $extends,
} $definition,
} $setUp);
public function writeDefinition(array $options, array $columns, array $relations = array()) return $content;
{ }
$content = $this->buildDefinition($options, $columns, $relations);
public function buildRecord(array $options, array $columns, array $relations = array(), array $indexes = array())
$code = "<?php\n"; {
if ( !isset($options['className'])) {
if (isset($options['requires'])) { throw new Doctrine_Import_Builder_Exception('Missing class name.');
if (!is_array($options['requires'])) { }
$options['requires'] = array($options['requires']);
} if ( !isset($options['fileName'])) {
if (empty($this->path)) {
foreach ($options['requires'] as $require) { throw new Doctrine_Import_Builder_Exception('No build target directory set.');
$code .= "require_once('".$require."');"; }
}
}
if (is_writable($this->path) === false) {
$code .= PHP_EOL . $content; throw new Doctrine_Import_Builder_Exception('Build target directory ' . $this->path . ' is not writable.');
}
$bytes = file_put_contents($options['fileName'], $code);
$options['fileName'] = $this->path . DIRECTORY_SEPARATOR . $options['className'] . $this->suffix;
if ($bytes === false) { }
throw new Doctrine_Import_Builder_Exception("Couldn't write file " . $options['fileName']);
} if ($this->generateBaseClasses()) {
}
// We only want to generate this one if it doesn't already exist
if (!file_exists($options['fileName'])) {
$optionsBak = $options;
unset($options['tableName']);
$options['inheritance']['extends'] = 'Base' . $options['className'];
$options['requires'] = array($this->baseClassesDirectory . DIRECTORY_SEPARATOR . $options['inheritance']['extends'] . $this->suffix);
$options['no_definition'] = true;
$this->writeDefinition($options, array(), array());
$options = $optionsBak;
}
$generatedPath = $this->path . DIRECTORY_SEPARATOR . $this->baseClassesDirectory;
if (!file_exists($generatedPath)) {
mkdir($generatedPath);
}
$options['className'] = 'Base' . $options['className'];
$options['abstract'] = true;
$options['fileName'] = $generatedPath . DIRECTORY_SEPARATOR . $options['className'] . $this->suffix;
$this->writeDefinition($options, $columns, $relations, $indexes);
} else {
$this->writeDefinition($options, $columns, $relations, $indexes);
}
}
public function writeDefinition(array $options, array $columns, array $relations = array(), array $indexes = array())
{
$content = $this->buildDefinition($options, $columns, $relations, $indexes);
$code = "<?php\n";
if (isset($options['requires'])) {
if (!is_array($options['requires'])) {
$options['requires'] = array($options['requires']);
}
foreach ($options['requires'] as $require) {
$code .= "require_once('".$require."');";
}
}
$code .= PHP_EOL . $content;
$bytes = file_put_contents($options['fileName'], $code);
if ($bytes === false) {
throw new Doctrine_Import_Builder_Exception("Couldn't write file " . $options['fileName']);
}
}
} }

View File

@ -26,7 +26,7 @@
* methods is simple. Some people will like the idea of producing Doctrine_Record * methods is simple. Some people will like the idea of producing Doctrine_Record
* objects directly, which is totally fine. But in fast and growing application, * objects directly, which is totally fine. But in fast and growing application,
* table definitions tend to be a little bit more volatile. importArr() can be used * table definitions tend to be a little bit more volatile. importArr() can be used
* to output a table definition in a PHP file. This file can then be stored * to output a table definition in a PHP file. This file can then be stored
* independantly from the object itself. * independantly from the object itself.
* *
* @package Doctrine * @package Doctrine
@ -40,6 +40,7 @@
class Doctrine_Import_Schema class Doctrine_Import_Schema
{ {
public $relations = array(); public $relations = array();
public $indexes = array();
public $generateBaseClasses = false; public $generateBaseClasses = false;
public function generateBaseClasses($bool = null) public function generateBaseClasses($bool = null)
@ -59,7 +60,7 @@ class Doctrine_Import_Schema
$this->buildRelationships($array); $this->buildRelationships($array);
return array('schema' => $array, 'relations' => $this->relations); return array('schema' => $array, 'relations' => $this->relations, 'indexes' => $this->indexes);
} }
/** /**
* importSchema * importSchema
@ -69,7 +70,7 @@ class Doctrine_Import_Schema
* @param string $schema The file containing the XML schema * @param string $schema The file containing the XML schema
* @param string $directory The directory where the Doctrine_Record class will be written * @param string $directory The directory where the Doctrine_Record class will be written
* @param array $models Optional array of models to import * @param array $models Optional array of models to import
* *
* @access public * @access public
*/ */
public function importSchema($schema, $format = 'yml', $directory = null, $models = array()) public function importSchema($schema, $format = 'yml', $directory = null, $models = array())
@ -89,7 +90,7 @@ class Doctrine_Import_Schema
$options = $this->getOptions($properties, $directory); $options = $this->getOptions($properties, $directory);
$columns = $this->getColumns($properties); $columns = $this->getColumns($properties);
$relations = $this->getRelations($properties); $relations = $this->getRelations($properties);
$builder->buildRecord($options, $columns, $relations); $builder->buildRecord($options, $columns, $relations);
} }
@ -118,11 +119,16 @@ class Doctrine_Import_Schema
{ {
return isset($this->relations[$properties['className']]) ? $this->relations[$properties['className']]:array(); return isset($this->relations[$properties['className']]) ? $this->relations[$properties['className']]:array();
} }
public function getIndexes($properties)
{
return isset($properties['indexes']) ? $properties['indexes']:array();;
}
/** /**
* parseSchema * parseSchema
* *
* A method to parse a Yml Schema and translate it into a property array. * A method to parse a Yml Schema and translate it into a property array.
* The function returns that property array. * The function returns that property array.
* *
* @param string $schema Path to the file containing the XML schema * @param string $schema Path to the file containing the XML schema
@ -164,6 +170,7 @@ class Doctrine_Import_Schema
$build[$className]['tableName'] = $tableName; $build[$className]['tableName'] = $tableName;
$build[$className]['columns'] = $columns; $build[$className]['columns'] = $columns;
$build[$className]['relations'] = isset($table['relations']) ? $table['relations']:array(); $build[$className]['relations'] = isset($table['relations']) ? $table['relations']:array();
$build[$className]['indexes'] = isset($table['indexes']) ? $table['indexes']:array();
} }
if (isset($table['inheritance'])) { if (isset($table['inheritance'])) {
@ -181,14 +188,14 @@ class Doctrine_Import_Schema
continue; continue;
} }
$className = $properties['className']; $className = $properties['className'];
$relations = $properties['relations']; $relations = $properties['relations'];
foreach ($relations as $alias => $relation) { foreach ($relations as $alias => $relation) {
$class = isset($relation['class']) ? $relation['class']:$alias; $class = isset($relation['class']) ? $relation['class']:$alias;
$relation['foreign'] = isset($relation['foreign'])?$relation['foreign']:'id'; $relation['foreign'] = isset($relation['foreign'])?$relation['foreign']:'id';
$relation['alias'] = isset($relation['alias']) ? $relation['alias'] : $alias; $relation['alias'] = isset($relation['alias']) ? $relation['alias'] : $alias;
$relation['class'] = $class; $relation['class'] = $class;
@ -236,7 +243,7 @@ class Doctrine_Import_Schema
if(isset($relation['foreignType'])) { if(isset($relation['foreignType'])) {
$newRelation['type'] = $relation['foreignType']; $newRelation['type'] = $relation['foreignType'];
} else { } else {
$newRelation['type'] = $relation['type'] === Doctrine_Relation::ONE ? Doctrine_Relation::MANY:Doctrine_Relation::ONE; $newRelation['type'] = $relation['type'] === Doctrine_Relation::ONE ? Doctrine_Relation::MANY:Doctrine_Relation::ONE;
} }
if( isset($this->relations[$relation['class']]) && is_array($this->relations[$relation['class']]) ) { if( isset($this->relations[$relation['class']]) && is_array($this->relations[$relation['class']]) ) {