SchemaBuilder.class.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************************
00003  *   Copyright (C) 2006-2008 by Konstantin V. Arkhipov                     *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU Lesser General Public License as        *
00007  *   published by the Free Software Foundation; either version 3 of the    *
00008  *   License, or (at your option) any later version.                       *
00009  *                                                                         *
00010  ***************************************************************************/
00011 
00015     final class SchemaBuilder extends BaseBuilder
00016     {
00017         public static function buildTable($tableName, array $propertyList)
00018         {
00019             $out = <<<EOT
00020 \$schema->
00021     addTable(
00022         DBTable::create('{$tableName}')->
00023 
00024 EOT;
00025 
00026             $columns = array();
00027             
00028             foreach ($propertyList as $property) {
00029                 if (
00030                     $property->getRelation()
00031                     && ($property->getRelationId() != MetaRelation::ONE_TO_ONE)
00032                 ) {
00033                     continue;
00034                 }
00035                 
00036                 $column = $property->toColumn();
00037                 
00038                 if (is_array($column))
00039                     $columns = array_merge($columns, $column);
00040                 else
00041                     $columns[] = $property->toColumn();
00042             }
00043             
00044             $out .= implode("->\n", $columns);
00045             
00046             return $out."\n);\n\n";
00047         }
00048         
00049         public static function buildRelations(MetaClass $class)
00050         {
00051             $out = null;
00052             
00053             $knownJunctions = array();
00054             
00055             foreach ($class->getAllProperties() as $property) {
00056                 if ($relation = $property->getRelation()) {
00057                     
00058                     $foreignClass = $property->getType()->getClass();
00059                     
00060                     if (
00061                         $relation->getId() == MetaRelation::ONE_TO_MANY
00062                         // nothing to build, it's in the same table
00063                         // or table does not exist at all
00064                         || !$foreignClass->getPattern()->tableExists()
00065                         // no need to process them
00066                         || $class->getParent()
00067                     ) {
00068                         continue;
00069                     } elseif (
00070                         $relation->getId() == MetaRelation::MANY_TO_MANY
00071                     ) {
00072                         $tableName =
00073                             $class->getTableName()
00074                             .'_'
00075                             .$foreignClass->getTableName();
00076                         
00077                         if (isset($knownJunctions[$tableName]))
00078                             continue; // collision prevention
00079                         else
00080                             $knownJunctions[$tableName] = true;
00081                         
00082                         $foreignPropery = clone $foreignClass->getIdentifier();
00083                         
00084                         $name = $class->getName();
00085                         $name = strtolower($name[0]).substr($name, 1);
00086                         $name .= 'Id';
00087                         
00088                         $foreignPropery->
00089                             setName($name)->
00090                             setColumnName($foreignPropery->getConvertedName())->
00091                             // we don't need primary key here
00092                             setIdentifier(false);
00093                         
00094                         // we don't want any garbage in such tables
00095                         $property = clone $property;
00096                         $property->required();
00097                         
00098                         // prevent name collisions
00099                         if (
00100                             $property->getRelationColumnName()
00101                             == $foreignPropery->getColumnName()
00102                         ) {
00103                             $foreignPropery->setColumnName(
00104                                 $class->getTableName().'_'
00105                                 .$property->getConvertedName().'_id'
00106                             );
00107                         }
00108                         
00109                         $out .= <<<EOT
00110 \$schema->
00111     addTable(
00112         DBTable::create('{$tableName}')->
00113         {$property->toColumn()}->
00114         {$foreignPropery->toColumn()}->
00115         addUniques('{$property->getRelationColumnName()}', '{$foreignPropery->getColumnName()}')
00116     );
00117 
00118 
00119 EOT;
00120                     } else {
00121                         $sourceTable = $class->getTableName();
00122                         $sourceColumn = $property->getRelationColumnName();
00123                         
00124                         $targetTable = $foreignClass->getTableName();
00125                         $targetColumn = $foreignClass->getIdentifier()->getColumnName();
00126                         
00127                         $out .= <<<EOT
00128 // {$sourceTable}.{$sourceColumn} -> {$targetTable}.{$targetColumn}
00129 \$schema->
00130     getTableByName('{$sourceTable}')->
00131         getColumnByName('{$sourceColumn}')->
00132             setReference(
00133                 \$schema->
00134                     getTableByName('{$targetTable}')->
00135                     getColumnByName('{$targetColumn}'),
00136                 ForeignChangeAction::restrict(),
00137                 ForeignChangeAction::cascade()
00138             );
00139 
00140 
00141 EOT;
00142                     
00143                     }
00144                 }
00145             }
00146             
00147             return $out;
00148         }
00149         
00150         public static function getHead()
00151         {
00152             $out = parent::getHead();
00153             
00154             $out .= "\$schema = new DBSchema();\n\n";
00155             
00156             return $out;
00157         }
00158     }
00159 ?>