Development

Changeset 7396

You must first sign up to be able to contribute.

Changeset 7396

Show
Ignore:
Timestamp:
02/08/08 00:51:14 (10 months ago)
Author:
dwhittle
Message:

dwhittle: merged changes to branch

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/dwhittle/1.1/lib/plugins/sfPropelPlugin/lib/propel/addon/sfPropelDatabaseSchema.class.php

    r6707 r7396  
    33/* 
    44 * This file is part of the symfony package. 
    5  * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com> 
     5 * (c) Fabien Potencier <fabien.potencier@symfony-project.com> 
     6 * (c) Francois Zaninotto <francois.zaninotto@symfony-project.com> 
    67 * 
    78 * For the full copyright and license information, please view the LICENSE 
     
    2829  } 
    2930 
     31  public function loadArray($schema_array) 
     32  { 
     33    $database = array(); 
     34    $connection_name = ''; 
     35 
     36    if (isset($schema_array['classes'])) 
     37    { 
     38      // New schema syntax 
     39      $schema_array = $this->convertNewToOldYaml($schema_array); 
     40    } 
     41 
     42    if (count($schema_array) > 1) 
     43    { 
     44      throw new sfException('A schema.yml must only contain 1 database entry.'); 
     45    } 
     46 
     47    $tmp = array_keys($schema_array); 
     48    $connection_name = array_shift($tmp); 
     49 
     50    if ($connection_name) 
     51    { 
     52      $database = $schema_array[$connection_name]; 
     53    } 
     54 
     55    $this->connection_name = $connection_name; 
     56    $this->database = $database; 
     57     
     58    $this->fixYAMLDatabase(); 
     59    $this->fixYAMLI18n(); 
     60    $this->fixYAMLColumns(); 
     61  } 
     62   
    3063  public function loadYAML($file) 
    3164  { 
    32     $schema = sfYaml::load($file); 
    33  
    34     if (count($schema) > 1) 
    35     { 
    36       throw new sfException('A schema.yml must only contain 1 database entry.'); 
    37     } 
     65    $schema_array = sfYaml::load($file); 
     66     
     67    if (!isset($schema_array['classes'])) 
     68    { 
     69      // Old schema syntax: we convert it  
     70      $schema_array = $this->convertOldToNewYaml($schema_array); 
     71    } 
     72     
     73    $this->loadArray($schema_array); 
     74  } 
     75   
     76  public function convertOldToNewYaml($schema) 
     77  { 
     78    $new_schema = array(); 
    3879 
    3980    $tmp = array_keys($schema); 
    40     $this->connection_name = array_shift($tmp); 
    41     if ($this->connection_name) 
    42     { 
    43       $this->database = $schema[$this->connection_name]; 
    44  
    45       $this->fixYAMLDatabase(); 
    46       $this->fixYAMLI18n(); 
    47       $this->fixYAMLColumns(); 
    48     } 
     81    $connection_name = array_shift($tmp); 
     82    $new_schema['connection'] = $connection_name; 
     83     
     84    $classes = array(); 
     85    foreach($schema[$connection_name] as $table => $table_params) 
     86    { 
     87      if ($table == '_attributes') 
     88      { 
     89        // Database attributes 
     90        $new_schema = array_merge($new_schema, $table_params); 
     91      } 
     92      else 
     93      { 
     94        // Table 
     95        $phpName = sfInflector::camelize($table); 
     96        if (isset($table_params['_attributes'])) 
     97        { 
     98          $table_attributes = $table_params['_attributes']; 
     99          unset($table_params['_attributes']); 
     100          if (isset($table_attributes['phpName'])) 
     101          { 
     102            $phpName = $table_attributes['phpName']; 
     103            unset($table_attributes['phpName']); 
     104          } 
     105        } 
     106        else 
     107        { 
     108          $table_attributes = array(); 
     109        } 
     110        $classes[$phpName] = $table_attributes; 
     111        $classes[$phpName]['tableName'] = $table; 
     112        $classes[$phpName]['columns'] = array(); 
     113        foreach($table_params as $column => $column_params) 
     114        { 
     115          switch($column) 
     116          { 
     117            case '_behaviors': 
     118              $classes[$phpName]['behaviors'] = $column_params; 
     119              break; 
     120            case '_foreignKeys': 
     121              $classes[$phpName]['foreignKeys'] = $column_params; 
     122              break; 
     123            case '_indexes': 
     124              $classes[$phpName]['indexes'] = $column_params; 
     125              break; 
     126            case '_uniques': 
     127              $classes[$phpName]['uniques'] = $column_params; 
     128              break; 
     129            default: 
     130              $classes[$phpName]['columns'][$column] = $column_params; 
     131          } 
     132        } 
     133      } 
     134    } 
     135     
     136    $new_schema['classes'] = $classes; 
     137     
     138    return $new_schema; 
     139  } 
     140   
     141  public function convertNewToOldYaml($schema) 
     142  { 
     143     
     144    if (isset($schema['connection'])) 
     145    { 
     146      $connection_name = $schema['connection']; 
     147      unset($schema['connection']); 
     148    } 
     149    else 
     150    { 
     151      $connection_name = 'propel'; 
     152    } 
     153     
     154    $database = array(); 
     155     
     156    // Tables 
     157    if (isset($schema['classes'])) 
     158    { 
     159      $tables = array(); 
     160      foreach ($schema['classes'] as $className => $classParams) 
     161      { 
     162        $tableParams = array();  
     163         
     164        // Columns 
     165        if (isset($classParams['columns'])) 
     166        { 
     167          $tableParams = array_merge($classParams['columns'], $tableParams); 
     168          unset($classParams['columns']); 
     169        } 
     170 
     171        // Indexes and foreign keys 
     172        if (isset($classParams['indexes'])) 
     173        { 
     174          $tableParams['_indexes'] = $classParams['indexes']; 
     175          unset($classParams['indexes']); 
     176        } 
     177        if (isset($classParams['uniques'])) 
     178        { 
     179          $tableParams['_uniques'] = $classParams['uniques']; 
     180          unset($classParams['uniques']); 
     181        } 
     182        if (isset($classParams['foreignKeys'])) 
     183        { 
     184          $tableParams['_foreignKeys'] = $classParams['foreignKeys']; 
     185          unset($classParams['foreignKeys']); 
     186        } 
     187         
     188        // Behaviors 
     189        if (isset($classParams['behaviors'])) 
     190        { 
     191          $tableParams['_behaviors'] = $classParams['behaviors']; 
     192          unset($classParams['behaviors']); 
     193        } 
     194         
     195        // Table attributes 
     196        $tableAttributes = array(); 
     197        if (isset($classParams['tableName'])) 
     198        { 
     199          $tableName = $classParams['tableName']; 
     200          unset($classParams['tableName']); 
     201        } 
     202        else 
     203        { 
     204          $tableName = sfInflector::underscore($className); 
     205        } 
     206         
     207        if (sfInflector::camelize($tableName) != $className) 
     208        { 
     209          $tableAttributes['phpName'] = $className; 
     210        } 
     211         
     212        if ($tableAttributes || $classParams) 
     213        { 
     214          $tableParams['_attributes'] = array_merge($tableAttributes, $classParams); 
     215        } 
     216         
     217        $tables[$tableName] = $tableParams; 
     218      } 
     219      $database = array_merge($database, $tables); 
     220      unset($schema['classes']); 
     221    } 
     222     
     223    // Database attributes 
     224    if ($schema) 
     225    { 
     226      $database['_attributes'] = $schema; 
     227    } 
     228     
     229    return array($connection_name => $database); 
    49230  } 
    50231 
     
    58239    foreach ($this->getChildren($this->database) as $tb_name => $table) 
    59240    { 
    60       $xml .= "\n  <table name=\"$tb_name\"".$this->getAttributesFor($table).">\n"; 
     241      $xml .= "\n  <table name=\"$tb_name\"".$this->getAttributesFor($table); 
     242      if (isset($table['_behaviors'])) 
     243      { 
     244        $xml .= sprintf(" behaviors=\"%s\"", htmlspecialchars(serialize($table['_behaviors']))); 
     245      } 
     246      $xml .= ">\n"; 
    61247 
    62248      // columns 
     
    227413              'required'      => true, 
    228414              'primaryKey'    => true, 
    229               'autoincrement' => true 
     415              'autoIncrement' => true 
    230416            ); 
    231417            $has_primary_key = true; 
     
    241427              $this->database[$table][$column] = array( 
    242428                'type'             => 'integer', 
    243                 'required'         => true, 
    244429                'foreignTable'     => $foreign_table, 
    245                 'foreignReference' => 'id', 
     430                'foreignReference' => 'id' 
    246431              ); 
    247432            } 
    248433            else 
    249434            { 
    250               throw new sfException(sprintf('Unable to resolve foreign table for column "%s"', $column)); 
     435              throw new sfException(sprintf('Unable to resolve foreign table for column "%s".', $column)); 
    251436            } 
    252437          } 
     438           
    253439        } 
    254440        else 
     
    281467          'required'      => true, 
    282468          'primaryKey'    => true, 
    283           'autoincrement' => true 
     469          'autoIncrement' => true 
    284470        ); 
    285471      } 
     
    314500    foreach ($this->getTables() as $tb_name => $table) 
    315501    { 
    316       if ((isset($table['_attributes']['phpName']) && $table['_attributes']['phpName'] == sfInflector::camelize($table_name)) || ($tb_name == $table_name)) 
     502      if ( 
     503           ($tb_name == $table_name) 
     504           || (isset($table['_attributes']['phpName']) &&  
     505             ( 
     506               $table['_attributes']['phpName'] == sfInflector::camelize($table_name)  
     507               || $table['_attributes']['phpName'] == $table_name 
     508             ) 
     509           || (sfInflector::underscore($table_name) == $tb_name))  
     510         ) 
    317511      { 
    318512        $table_match = $tb_name; 
     513        break; 
    319514      } 
    320515    } 
     
    330525      foreach ($column as $key => $value) 
    331526      { 
    332         if (!in_array($key, array('foreignTable', 'foreignReference', 'onDelete', 'onUpdate', 'index', 'unique'))) 
     527        if (!in_array($key, array('foreignClass', 'foreignTable', 'foreignReference', 'onDelete', 'onUpdate', 'index', 'unique', 'sequence'))) 
    333528        { 
    334529          $attributes_string .= " $key=\"".htmlspecialchars($this->getCorrectValueFor($key, $value))."\""; 
     
    339534    else 
    340535    { 
    341       throw new sfException(sprintf('Incorrect settings for column %s', $col_name)); 
     536      throw new sfException(sprintf('Incorrect settings for column "%s".', $col_name)); 
    342537    } 
    343538 
    344539    // conventions for foreign key attributes 
    345     if (is_array($column) && isset($column['foreignTable'])) 
    346     { 
    347       $attributes_string .= "    <foreign-key foreignTable=\"$column[foreignTable]\""; 
     540    if (is_array($column) && (isset($column['foreignTable']) || isset($column['foreignClass']))) 
     541    { 
     542      if (isset($column['foreignTable'])) 
     543      { 
     544        $attributes_string .= "    <foreign-key foreignTable=\"$column[foreignTable]\""; 
     545      } 
     546      else 
     547      { 
     548        $foreignTable = $this->findTable($column['foreignClass']); 
     549        if (!$foreignTable) 
     550        { 
     551          // Let's assume that the class given is from another schema 
     552          // We have no access to the other schema's phpNames 
     553          // So our last guess is to try to underscore the class name 
     554          $foreignTable = sfInflector::underscore($column['foreignClass']); 
     555        } 
     556        $attributes_string .= "    <foreign-key foreignTable=\"".$foreignTable."\""; 
     557      } 
     558       
    348559      if (isset($column['onDelete'])) 
    349560      { 
     
    660871      foreach ($columns as $column => $attributes) 
    661872      { 
    662         if ($column == 'id' && !array_diff($attributes, array('type' => 'integer', 'required' => 'true', 'primaryKey' => 'true', 'autoincrement' => 'true'))) 
     873        if ($column == 'id' && !array_diff($attributes, array('type' => 'integer', 'required' => 'true', 'primaryKey' => 'true', 'autoIncrement' => 'true'))) 
    663874        { 
    664875          // simplify primary keys 
     
    705916    foreach ($hash as $attribute => $value) 
    706917    { 
    707       $attributes[$attribute] = strval($value)
     918      $attributes[$attribute] = (string) $value
    708919    } 
    709920 
  • branches/dwhittle/1.1/lib/plugins/sfPropelPlugin/lib/propel/builder/SfObjectBuilder.php

    r6707 r7396  
    349349    $script .= $tmp; 
    350350  } 
     351   
     352  protected function addClassClose(&$script) 
     353  { 
     354    parent::addClassClose($script); 
     355     
     356    $behaviors = $this->getTable()->getAttribute('behaviors'); 
     357    if($behaviors) 
     358    { 
     359      $behavior_file_name = 'Base'.$this->getTable()->getPhpName().'Behaviors'; 
     360      $behavior_file_path = $this->getFilePath($this->getStubObjectBuilder()->getPackage().'.om.'.$behavior_file_name); 
     361      $script .= sprintf("\n\ninclude_once '%s';\n", $behavior_file_path); 
     362    } 
     363  } 
    351364} 
  • branches/dwhittle/1.1/lib/plugins/sfPropelPlugin/lib/propel/builder/SfPeerBuilder.php

    r7200 r7396  
    389389    $script .= $tmp; 
    390390  } 
     391   
     392  protected function addClassClose(&$script) 
     393  { 
     394    parent::addClassClose($script); 
     395 
     396    $behavior_file_name = 'Base'.$this->getTable()->getPhpName().'Behaviors'; 
     397    $behavior_file_path = $this->getFilePath($this->getStubObjectBuilder()->getPackage().'.om.'.$behavior_file_name); 
     398    $absolute_behavior_file_path = sfConfig::get('sf_root_dir').'/'.$behavior_file_path; 
     399     
     400    if(file_exists($absolute_behavior_file_path)) 
     401    { 
     402      unlink($absolute_behavior_file_path); 
     403    } 
     404     
     405    $behaviors = $this->getTable()->getAttribute('behaviors'); 
     406    if($behaviors) 
     407    { 
     408      file_put_contents($absolute_behavior_file_path, sprintf("<?php\nsfPropelBehavior::add('%s', %s);\n", $this->getTable()->getPhpName(), var_export(unserialize($behaviors), true))); 
     409      $script .= sprintf("\n\ninclude_once '%s';\n", $behavior_file_path); 
     410    } 
     411  } 
    391412} 
  • branches/dwhittle/1.1/lib/plugins/sfPropelPlugin/lib/task/sfPropelBaseTask.class.php

    r7349 r7396  
    103103 
    104104    $dbSchema = new sfPropelDatabaseSchema(); 
     105     
    105106    foreach ($schemas as $schema) 
    106107    { 
    107       $dbSchema->loadYAML($schema); 
     108      $schemaArray = sfYaml::load($schema); 
     109       
     110      if (!isset($schema_array['classes'])) 
     111      { 
     112        // Old schema syntax: we convert it  
     113        $schemaArray = $dbSchema->convertOldToNewYaml($schemaArray); 
     114      } 
     115 
     116      $customSchemaFilename = str_replace(array(sfConfig::get('sf_root_dir').DIRECTORY_SEPARATOR, 'plugins'.DIRECTORY_SEPARATOR, 'config'.DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR, 'schema.yml'), array('', '', '', '_', 'schema.custom.yml'), $schema); 
     117      $customSchemas = sfFinder::type('file')->name($customSchemaFilename)->in($dirs); 
     118       
     119      foreach ($customSchemas as $customSchema) 
     120      { 
     121        $this->dispatcher->notify(new sfEvent($this, 'command.log', array($this->formatter->formatSection('schema', sprintf('found custom schema %s', $customSchema))))); 
     122         
     123        $customSchemaArray = sfYaml::load($customSchema); 
     124        if (!isset($customSchemaArray['classes'])) 
     125        { 
     126          // Old schema syntax: we convert it  
     127          $customSchemaArray = $dbSchema->convertOldToNewYaml($customSchemaArray); 
     128        } 
     129        $schemaArray = sfToolkit::arrayDeepMerge($schemaArray, $customSchemaArray); 
     130      } 
     131 
     132      $dbSchema->loadArray($schemaArray); 
    108133 
    109134      $this->dispatcher->notify(new sfEvent($this, 'command.log', array($this->formatter->formatSection('schema', sprintf('converting "%s" to XML', $schema))))); 
  • branches/dwhittle/1.1/lib/plugins/sfPropelPlugin/test/unit/fixtures/schema.yml

    r5125 r7396  
    11propel: 
    2   some_table: 
    3     _attributes:    { phpName: SomeTable } 
    4     somechar:       { type: VARCHAR, size: 255, default: "This & That" } 
     2  _attributes:      { noXsd: false, defaultIdMethod: none, package: lib.model } 
     3  ab_group: 
     4    _attributes:    { phpName: Group, package: foo.bar.lib.model } 
     5    id: 
     6    name:           varchar(50) 
     7     
     8  cd_user: 
     9    _attributes:    { phpName: User, isI18N: true, i18nTable: cd_user_i18n } 
     10    first_name:     { type: varchar, size: 255, default: "Anonymous" } 
     11    last_name:      varchar(50) 
     12    age:            { type: integer, required: true, index: true } 
     13    ab_group_id: 
     14    created_at: 
     15   
     16  cd_user_i18n: 
     17    description:    longvarchar 
     18     
     19  ef_article: 
     20    title:          { type: longvarchar, required: true, index: unique } 
     21    stripped_title: { type: longvarchar, required: true, primaryKey: true, sequence: my_custom_sequence_name } 
     22    user_id: 
     23    my_group:       { type: integer, foreignTable: ab_group, foreignReference: id, onDelete: setnull } 
     24    my_other_group: { type: integer, foreignTable: ab_group, foreignReference: id, onDelete: setnull } 
     25    created_at:     timestamp 
     26    updated_at: 
     27 
     28  ij_article: 
     29    _attributes:    { phpName: Article } 
     30    title:          varchar(50) 
     31    user_id:        { type: integer } 
     32    _foreignKeys: 
     33      - 
     34        foreignTable: cd_user 
     35        onDelete:     cascade 
     36        references: 
     37          - { local: user_id, foreign: id } 
     38    created_at: 
     39    _indexes: 
     40      my_index:       [title, user_id] 
     41    _uniques: 
     42      my_other_index: [created_at] 
     43    _behaviors: 
     44      paranoid: { column: deleted_at } 
     45      act_as_nested_set: 
     46   
     47  ab_group_i18n: 
     48    motto:            longvarchar 
  • branches/dwhittle/1.1/lib/plugins/sfPropelPlugin/test/unit/sfPropelDatabaseSchemaTest.php

    r5125 r7396  
    33/* 
    44 * This file is part of the symfony package. 
    5  * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com> 
    6  *  
     5 * (c) Fabien Potencier <fabien.potencier@symfony-project.com> 
     6 * (c) Francois Zaninotto <francois.zaninotto@symfony-project.com> 
     7 * 
    78 * For the full copyright and license information, please view the LICENSE 
    89 * file that was distributed with this source code. 
     
    1112require_once(dirname(__FILE__).'/../../../../../test/bootstrap/unit.php'); 
    1213 
    13 $t = new lime_test(1, new lime_output_color()); 
     14class my_lime_test extends lime_test 
     15
     16  public function is_array_explicit($test, $target, $prefix = '') 
     17  { 
     18    foreach ($test as $key => $value) 
     19    { 
     20      if (is_array($value)) 
     21      { 
     22        $this->is_array_explicit($value, $target[$key], $prefix.' '.$key); 
     23      } 
     24      else 
     25      { 
     26        $this->is($value, $target[$key], sprintf('%s %s is %s', $prefix, $key, $value)); 
     27      } 
     28    } 
     29  } 
    1430 
     31  public function is_line_by_line($exp1, $exp2) 
     32  { 
     33    $array_exp1 = explode("\n", $exp1); 
     34    $array_exp2 = explode("\n", $exp2); 
     35    $nb_lines = count($array_exp1); 
     36    for ($i=0; $i < $nb_lines; $i++) 
     37    { 
     38      if(!$array_exp1[$i]) continue; // Skip blank lines to avoid testing nothing 
     39      $this->is(trim($array_exp1[$i]), trim($array_exp2[$i]), sprintf('Line %d matches %s', $i, $array_exp1[$i])); 
     40    } 
     41  } 
     42} 
     43 
     44require_once(dirname(__FILE__).'/../../../../../test/bootstrap/unit.php'); 
     45require_once(dirname(__FILE__).'/../../lib/propel/addon/sfPropelDatabaseSchema.class.php'); 
     46require_once(dirname(__FILE__).'/../../../../util/sfInflector.class.php'); 
     47require_once(dirname(__FILE__).'/../../../../util/sfToolkit.class.php'); 
     48require_once(dirname(__FILE__).'/../../../../util/sfYaml.class.php'); 
     49 
     50$t = new my_lime_test(261, new lime_output_color()); 
     51 
     52$t->diag('Classical YAML to XML conversion'); 
    1553$p = new sfPropelDatabaseSchema(); 
    1654$p->loadYAML(dirname(__FILE__).'/fixtures/schema.yml'); 
    17 $t->like($p->asXML(), '/This &amp; That/'); 
     55$target = file_get_contents(dirname(__FILE__).'/fixtures/schema.xml'); 
     56$t->is_line_by_line($p->asXML(), $target); 
     57 
     58$t->diag('New YAML to XML conversion'); 
     59$p = new sfPropelDatabaseSchema(); 
     60$p->loadYAML(dirname(__FILE__).'/fixtures/new_schema.yml'); 
     61$target = file_get_contents(dirname(__FILE__).'/fixtures/schema.xml'); 
     62$t->is_line_by_line($p->asXML(), $target); 
     63 
     64$t->diag('New YAML to Old YAML conversion'); 
     65$old_yml_target = sfYaml::load(dirname(__FILE__).'/fixtures/schema.yml'); 
     66$p = new sfPropelDatabaseSchema(); 
     67$new_yml_transformed = $p->convertNewToOldYaml(sfYaml::load(dirname(__FILE__).'/fixtures/new_schema.yml')); 
     68$t->is_array_explicit($new_yml_transformed, $old_yml_target); 
     69 
     70$t->diag('Old YAML to New YAML conversion'); 
     71$new_yml_target = sfYaml::load(dirname(__FILE__).'/fixtures/new_schema.yml'); 
     72$p = new sfPropelDatabaseSchema(); 
     73$old_yml_transformed = $p->convertOldToNewYaml(sfYaml::load(dirname(__FILE__).'/fixtures/schema.yml')); 
     74$t->is_array_explicit($old_yml_transformed, $new_yml_target); 
     75 
     76 
     77$t->todo('XML and classical YAML internal representation'); 
     78$p1 = new sfPropelDatabaseSchema(); 
     79$p1->loadXML(dirname(__FILE__).'/fixtures/schema.xml'); 
     80$p2 = new sfPropelDatabaseSchema(); 
     81$p2->loadYAML(dirname(__FILE__).'/fixtures/schema.yml'); 
     82//$t->is_array_explicit($p1->asArray(), $p2->asArray()); 
     83 
     84$t->todo('XML and classical YAML compared as XML'); 
     85//$t->is_line_by_line($p1->asXML(), $p2->asXML()); 
     86 
     87$t->todo('XML and classical YAML compared as YAML'); 
     88//$t->is_line_by_line($p1->asYAML(), $p2->asYAML());