From 6ee5df4aab5c796ed04dd1766785ee04c875990d Mon Sep 17 00:00:00 2001
From: "Jonathan.Wage" <Jonathan.Wage@625475ce-881a-0410-a577-b389adb331d8>
Date: Tue, 16 Oct 2007 23:33:14 +0000
Subject: [PATCH] Addex support for indexes and attributes to schema.

---
 lib/Doctrine/Export.php         |   2 +-
 lib/Doctrine/Import/Builder.php | 158 +++++++++++++++++++-------------
 lib/Doctrine/Import/Schema.php  |  57 ++++++++----
 3 files changed, 137 insertions(+), 80 deletions(-)

diff --git a/lib/Doctrine/Export.php b/lib/Doctrine/Export.php
index 4e7e6094d..dd840d342 100644
--- a/lib/Doctrine/Export.php
+++ b/lib/Doctrine/Export.php
@@ -1050,7 +1050,7 @@ class Doctrine_Export extends Doctrine_Connection_Module
                     // we only want to silence table already exists errors
                     if ($e->getPortableCode() !== Doctrine::ERR_ALREADY_EXISTS) {
                         $connection->rollback();
-                        throw $e;
+                        throw new Doctrine_Export_Exception($e->getMessage() . '. Failing Query: ' . $query);
                     }
                 }
             }
diff --git a/lib/Doctrine/Import/Builder.php b/lib/Doctrine/Import/Builder.php
index 5f8f0edc2..d14e06ea8 100644
--- a/lib/Doctrine/Import/Builder.php
+++ b/lib/Doctrine/Import/Builder.php
@@ -193,7 +193,7 @@ END;
      * @param  string $table
      * @param  array  $tableColumns
      */
-    public function buildTableDefinition(array $options, array $columns, array $relations, array $indexes)
+    public function buildTableDefinition(array $options, array $columns, array $relations, array $indexes, array $attributes)
     {
         $ret = array();
         
@@ -257,65 +257,99 @@ END;
             $i++;
         }
         
-        foreach ($indexes as $indexName => $definitions) {
-            $ret[$i] = "\n".'        $this->index(\'' . $indexName . '\', array(';
-            
-            foreach ($definitions as $name => $value) {
-              
-              // parse fields
-              if ($name === 'fields') {
-                $ret[$i] .= '\'fields\' => array(';
-                
-                foreach ($value as $fieldName => $fieldValue) {
-                  $ret[$i] .= '\'' . $fieldName . '\' => array( ';
-                  
-                  // parse options { sorting, length, primary }
-                  if (isset($fieldValue) && $fieldValue) {
-                    foreach ($fieldValue as $optionName => $optionValue) {
-                      
-                      $ret[$i] .= '\'' . $optionName . '\' => ';
-                      
-                      // check primary option, mark either as true or false
-                      if ($optionName === 'primary') {
-                      	$ret[$i] .= (($optionValue == 'true') ? 'true' : 'false') . ', ';
-                      	continue;
-                      }
-                      
-                      // convert sorting option to uppercase, for instance, asc -> ASC
-                      if ($optionName === 'sorting') {
-                      	$ret[$i] .= '\'' . strtoupper($optionValue) . '\', ';
-                      	continue;
-                      }
-                      
-                      // check the rest of the options
-                      $ret[$i] .= '\'' . $optionValue . '\', ';
-                    }
-                  }
-                                    
-                  $ret[$i] .= '), ';
-                }
-              }
-              
-              // parse index type option, 4 choices { unique, fulltext, gist, gin }
-              if ($name === 'type') {
-              	$ret[$i] .= '), \'type\' => \'' . $value . '\'';
-              }
-              
-              // add extra ) if type definition is not declared
-              if (!isset($definitions['type'])) {
-              	$ret[$i] .= ')';
-              }
-            }
-            
-            $ret[$i] .= '));';
-            $i++;
-        }
+        $ret[$i] = $this->buildIndexes($indexes);
+        $i++;
+        
+        $ret[$i] = $this->buildAttributes($attributes);
+        $i++;
         
         if (!empty($ret)) {
           return "\n\tpublic function setTableDefinition()"."\n\t{\n".implode("\n", $ret)."\n\t}";
         }
     }
     
+    public function buildAttributes(array $attributes)
+    {
+        $build = "\n";
+        foreach ($attributes as $key => $value) {
+            if (!is_array($value)) {
+                $value = array($value);
+            }
+            
+            $values = '';
+            foreach ($value as $attr) {
+                $values .= "Doctrine::" . strtoupper($key) . "_" . strtoupper($attr) . ' ^ ';
+            }
+            
+            // Trim last ^
+            $values = substr($values, 0, strlen($values) - 3);
+            
+            $build .= "\t\t\$this->setAttribute(Doctrine::ATTR_" . strtoupper($key) . ", " . $values . ");\n";
+        }
+        
+        return $build;
+    }
+    
+    public function buildIndexes(array $indexes)
+    {
+      $build = '';
+
+      foreach ($indexes as $indexName => $definitions) {
+          $build = "\n".'        $this->index(\'' . $indexName . '\', array(';
+
+          foreach ($definitions as $name => $value) {
+
+            // parse fields
+            if ($name === 'fields' || $name === 'columns') {
+              $build .= '\'fields\' => array(';
+
+              foreach ($value as $fieldName => $fieldValue) {
+                $build .= '\'' . $fieldName . '\' => array( ';
+
+                // parse options { sorting, length, primary }
+                if (isset($fieldValue) && $fieldValue) {
+                  foreach ($fieldValue as $optionName => $optionValue) {
+
+                    $build .= '\'' . $optionName . '\' => ';
+
+                    // check primary option, mark either as true or false
+                    if ($optionName === 'primary') {
+                    	$build .= (($optionValue == 'true') ? 'true' : 'false') . ', ';
+                    	continue;
+                    }
+
+                    // convert sorting option to uppercase, for instance, asc -> ASC
+                    if ($optionName === 'sorting') {
+                    	$build .= '\'' . strtoupper($optionValue) . '\', ';
+                    	continue;
+                    }
+
+                    // check the rest of the options
+                    $build .= '\'' . $optionValue . '\', ';
+                  }
+                }
+
+                $build .= '), ';
+              }
+            }
+
+            // parse index type option, 4 choices { unique, fulltext, gist, gin }
+            if ($name === 'type') {
+            	$build .= '), \'type\' => \'' . $value . '\'';
+            }
+
+            // add extra ) if type definition is not declared
+            if (!isset($definitions['type'])) {
+            	$build .= ')';
+            }
+          }
+
+          $build .= '));';
+      }
+
+      return $build;
+    }
+    
     public function buildSetUp(array $options, array $columns, array $relations)
     {
         $ret = array();
@@ -387,7 +421,7 @@ END;
         }
     }
     
-    public function buildDefinition(array $options, array $columns, array $relations = array(), array $indexes = array())
+    public function buildDefinition(array $options, array $columns, array $relations = array(), array $indexes = array(), $attributes = array())
     {
         if ( ! isset($options['className'])) {
             throw new Doctrine_Import_Builder_Exception('Missing class name.');
@@ -398,7 +432,7 @@ END;
         $extends = isset($options['inheritance']['extends']) ? $options['inheritance']['extends']:'Doctrine_Record';
 
         if (!(isset($options['no_definition']) && $options['no_definition'] === true)) {
-            $definition = $this->buildTableDefinition($options, $columns, $relations, $indexes);
+            $definition = $this->buildTableDefinition($options, $columns, $relations, $indexes, $attributes);
             $setUp = $this->buildSetUp($options, $columns, $relations);
         } else {
             $definition = null;
@@ -417,7 +451,7 @@ END;
         return $content;
     }
 
-    public function buildRecord(array $options, array $columns, array $relations = array(), array $indexes = array())
+    public function buildRecord(array $options, array $columns, array $relations = array(), array $indexes = array(), array $attributes = array())
     {
         if ( !isset($options['className'])) {
             throw new Doctrine_Import_Builder_Exception('Missing class name.');
@@ -447,7 +481,7 @@ END;
             $options['requires'] = array($this->baseClassesDirectory . DIRECTORY_SEPARATOR  . $options['inheritance']['extends'] . $this->suffix);
             $options['no_definition'] = true;
             
-            $this->writeDefinition($options, array(), array(), array());
+            $this->writeDefinition($options);
             
             $options = $optionsBak;
           }
@@ -463,15 +497,15 @@ END;
           $options['fileName']  = $generatedPath . DIRECTORY_SEPARATOR . $options['className'] . $this->suffix;
           $options['override_parent'] = true;
           
-          $this->writeDefinition($options, $columns, $relations, $indexes);
+          $this->writeDefinition($options, $columns, $relations, $indexes, $attributes);
         } else {
-          $this->writeDefinition($options, $columns, $relations, $indexes);
+          $this->writeDefinition($options, $columns, $relations, $indexes, $attributes);
         }
     }
     
-    public function writeDefinition(array $options, array $columns, array $relations = array(), array $indexes = array())
+    public function writeDefinition(array $options, array $columns = array(), array $relations = array(), array $indexes = array(), array $attributes = array())
     {
-        $content = $this->buildDefinition($options, $columns, $relations, $indexes);
+        $content = $this->buildDefinition($options, $columns, $relations, $indexes, $attributes);
         $code = "<?php\n";
 
         if (isset($options['requires'])) {
diff --git a/lib/Doctrine/Import/Schema.php b/lib/Doctrine/Import/Schema.php
index 103ad4224..545688387 100644
--- a/lib/Doctrine/Import/Schema.php
+++ b/lib/Doctrine/Import/Schema.php
@@ -120,8 +120,9 @@ class Doctrine_Import_Schema
             $columns = $this->getColumns($properties);
             $relations = $this->getRelations($properties);
             $indexes = $this->getIndexes($properties);
+            $attributes = $this->getAttributes($properties);
             
-            $builder->buildRecord($options, $columns, $relations, $indexes);
+            $builder->buildRecord($options, $columns, $relations, $indexes, $attributes);
         }
     }
     
@@ -134,16 +135,16 @@ class Doctrine_Import_Schema
      */
     public function getOptions($properties, $directory)
     {
-      $options = array();
-      $options['className'] = $properties['className'];
-      $options['fileName'] = $directory.DIRECTORY_SEPARATOR.$properties['className'].'.class.php';
-      $options['tableName'] = isset($properties['tableName']) ? $properties['tableName']:null;
-      
-      if (isset($properties['inheritance'])) {
-          $options['inheritance'] = $properties['inheritance'];
-      }
-      
-      return $options;
+        $options = array();
+        $options['className'] = $properties['className'];
+        $options['fileName'] = $directory.DIRECTORY_SEPARATOR.$properties['className'].'.class.php';
+        $options['tableName'] = isset($properties['tableName']) ? $properties['tableName']:null;
+
+        if (isset($properties['inheritance'])) {
+            $options['inheritance'] = $properties['inheritance'];
+        }
+
+        return $options;
     }
     
     /**
@@ -154,7 +155,7 @@ class Doctrine_Import_Schema
      */
     public function getColumns($properties)
     {
-      return isset($properties['columns']) ? $properties['columns']:array();
+        return isset($properties['columns']) ? $properties['columns']:array();
     }
     
     /**
@@ -165,12 +166,29 @@ class Doctrine_Import_Schema
      */
     public function getRelations($properties)
     {
-      return isset($this->relations[$properties['className']]) ? $this->relations[$properties['className']]:array();
+        return isset($this->relations[$properties['className']]) ? $this->relations[$properties['className']]:array();
     }
-
+    
+    /**
+     * getIndexes
+     *
+     * @param string $properties 
+     * @return void
+     */
     public function getIndexes($properties)
     {
-      return isset($properties['indexes']) ? $properties['indexes']:array();;
+        return isset($properties['indexes']) ? $properties['indexes']:array();;
+    }
+    
+    /**
+     * getAttributes
+     *
+     * @param string $properties 
+     * @return void
+     */
+    public function getAttributes($properties)
+    {
+        return isset($properties['attributes']) ? $properties['attributes']:array();
     }
     
     /**
@@ -196,13 +214,17 @@ class Doctrine_Import_Schema
             
             $build[$className]['className'] = $className;
             
-            if (isset($table['columns'])) {
-                foreach ($table['columns'] as $columnName => $field) {
+            $columns = isset($table['columns']) ? $table['columns']:array();
+            $columns = isset($table['fields']) ? $table['fields']:$columns;
+            
+            if (!empty($columns)) {
+                foreach ($columns as $columnName => $field) {
                     $colDesc = array();
                     $colDesc['name'] = isset($field['name']) ? (string) $field['name']:$columnName;
                     $colDesc['type'] = isset($field['type']) ? (string) $field['type']:null;
                     $colDesc['ptype'] = isset($field['ptype']) ? (string) $field['ptype']:(string) $colDesc['type'];
                     $colDesc['length'] = isset($field['length']) ? (int) $field['length']:null;
+                    $colDesc['length'] = isset($field['size']) ? (int) $field['size']:$field['length'];
                     $colDesc['fixed'] = isset($field['fixed']) ? (int) $field['fixed']:null;
                     $colDesc['unsigned'] = isset($field['unsigned']) ? (bool) $field['unsigned']:null;
                     $colDesc['primary'] = isset($field['primary']) ? (bool) (isset($field['primary']) && $field['primary']):null;
@@ -219,6 +241,7 @@ class Doctrine_Import_Schema
                 $build[$className]['columns'] = $columns;
                 $build[$className]['relations'] = isset($table['relations']) ? $table['relations']:array();
                 $build[$className]['indexes'] = isset($table['indexes']) ? $table['indexes']:array();
+                $build[$className]['attributes'] = isset($table['attributes']) ? $table['attributes']:array();
             }
             
             if (isset($table['inheritance'])) {