]> git.andy128k.dev Git - ipf-legacy-orm.git/commitdiff
rewrite column export
authorAndrey Kutejko <andy128k@gmail.com>
Sat, 27 Jul 2013 10:21:22 +0000 (13:21 +0300)
committerAndrey Kutejko <andy128k@gmail.com>
Sat, 27 Jul 2013 10:21:22 +0000 (13:21 +0300)
ipf/orm/connection.php
ipf/orm/datadict.php [deleted file]
ipf/orm/datadict/mysql.php [deleted file]
ipf/orm/export.php
ipf/orm/export/mysql.php

index fc163e1646f87cf3f6a512452279e074aa9e4f1f..0acb3f5970c314c8bb8aa09c95b50c07087292e9 100644 (file)
@@ -12,7 +12,6 @@ abstract class IPF_ORM_Connection extends IPF_ORM_Configurable implements Counta
 
     private $modules = array('transaction' => false,
                              'expression'  => false,
-                             'dataDict'    => false,
                              'export'      => false,
                              'import'      => false,
                              'unitOfWork'  => false,
diff --git a/ipf/orm/datadict.php b/ipf/orm/datadict.php
deleted file mode 100644 (file)
index 56a2098..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-<?php
-
-class IPF_ORM_DataDict extends IPF_ORM_Connection_Module
-{
-    public function compareDefinition($current, $previous)
-    {
-        $type = !empty($current['type']) ? $current['type'] : null;
-
-        if ( ! method_exists($this, "_compare{$type}Definition")) {
-            throw new IPF_ORM_Exception('type "'.$current['type'].'" is not yet supported');
-        }
-
-        if (empty($previous['type']) || $previous['type'] != $type) {
-            return $current;
-        }
-
-        $change = $this->{"_compare{$type}Definition"}($current, $previous);
-
-        if ($previous['type'] != $type) {
-            $change['type'] = true;
-        }
-
-        $previous_notnull = !empty($previous['notnull']) ? $previous['notnull'] : false;
-        $notnull = !empty($current['notnull']) ? $current['notnull'] : false;
-        if ($previous_notnull != $notnull) {
-            $change['notnull'] = true;
-        }
-
-        $previous_default = array_key_exists('default', $previous) ? $previous['default'] :
-            ($previous_notnull ? '' : null);
-        $default = array_key_exists('default', $current) ? $current['default'] :
-            ($notnull ? '' : null);
-        if ($previous_default !== $default) {
-            $change['default'] = true;
-        }
-
-        return $change;
-    }
-}
-
diff --git a/ipf/orm/datadict/mysql.php b/ipf/orm/datadict/mysql.php
deleted file mode 100644 (file)
index ac55770..0000000
+++ /dev/null
@@ -1,372 +0,0 @@
-<?php
-
-class IPF_ORM_DataDict_Mysql extends IPF_ORM_DataDict
-{
-    protected $keywords = array(
-                          'ADD', 'ALL', 'ALTER',
-                          'ANALYZE', 'AND', 'AS',
-                          'ASC', 'ASENSITIVE', 'BEFORE',
-                          'BETWEEN', 'BIGINT', 'BINARY',
-                          'BLOB', 'BOTH', 'BY', 'BIT',
-                          'CALL', 'CASCADE', 'CASE',
-                          'CHANGE', 'CHAR', 'CHARACTER',
-                          'CHECK', 'COLLATE', 'COLUMN',
-                          'CONDITION', 'CONNECTION', 'CONSTRAINT',
-                          'CONTINUE', 'CONVERT', 'CREATE',
-                          'CROSS', 'CURRENT_DATE', 'CURRENT_TIME',
-                          'CURRENT_TIMESTAMP', 'CURRENT_USER', 'CURSOR',
-                          'DATABASE', 'DATABASES', 'DAY_HOUR',
-                          'DAY_MICROSECOND', 'DAY_MINUTE', 'DAY_SECOND',
-                          'DEC', 'DECIMAL', 'DECLARE',
-                          'DEFAULT', 'DELAYED', 'DELETE',
-                          'DESC', 'DESCRIBE', 'DETERMINISTIC',
-                          'DISTINCT', 'DISTINCTROW', 'DIV',
-                          'DOUBLE', 'DROP', 'DUAL',
-                          'EACH', 'ELSE', 'ELSEIF',
-                          'ENCLOSED', 'ESCAPED', 'EXISTS',
-                          'EXIT', 'EXPLAIN', 'FALSE',
-                          'FETCH', 'FLOAT', 'FLOAT4',
-                          'FLOAT8', 'FOR', 'FORCE',
-                          'FOREIGN', 'FROM', 'FULLTEXT',
-                          'GRANT', 'GROUP', 'HAVING',
-                          'HIGH_PRIORITY', 'HOUR_MICROSECOND', 'HOUR_MINUTE',
-                          'HOUR_SECOND', 'IF', 'IGNORE',
-                          'IN', 'INDEX', 'INFILE',
-                          'INNER', 'INOUT', 'INSENSITIVE',
-                          'INSERT', 'INT', 'INT1',
-                          'INT2', 'INT3', 'INT4',
-                          'INT8', 'INTEGER', 'INTERVAL',
-                          'INTO', 'IS', 'ITERATE',
-                          'JOIN', 'KEY', 'KEYS',
-                          'KILL', 'LEADING', 'LEAVE',
-                          'LEFT', 'LIKE', 'LIMIT',
-                          'LINES', 'LOAD', 'LOCALTIME',
-                          'LOCALTIMESTAMP', 'LOCK', 'LONG',
-                          'LONGBLOB', 'LONGTEXT', 'LOOP',
-                          'LOW_PRIORITY', 'MATCH', 'MEDIUMBLOB',
-                          'MEDIUMINT', 'MEDIUMTEXT', 'MIDDLEINT',
-                          'MINUTE_MICROSECOND', 'MINUTE_SECOND', 'MOD',
-                          'MODIFIES', 'NATURAL', 'NOT',
-                          'NO_WRITE_TO_BINLOG', 'NULL', 'NUMERIC',
-                          'ON', 'OPTIMIZE', 'OPTION',
-                          'OPTIONALLY', 'OR', 'ORDER',
-                          'OUT', 'OUTER', 'OUTFILE',
-                          'PRECISION', 'PRIMARY', 'PROCEDURE',
-                          'PURGE', 'RAID0', 'READ',
-                          'READS', 'REAL', 'REFERENCES',
-                          'REGEXP', 'RELEASE', 'RENAME',
-                          'REPEAT', 'REPLACE', 'REQUIRE',
-                          'RESTRICT', 'RETURN', 'REVOKE',
-                          'RIGHT', 'RLIKE', 'SCHEMA',
-                          'SCHEMAS', 'SECOND_MICROSECOND', 'SELECT',
-                          'SENSITIVE', 'SEPARATOR', 'SET',
-                          'SHOW', 'SMALLINT', 'SONAME',
-                          'SPATIAL', 'SPECIFIC', 'SQL',
-                          'SQLEXCEPTION', 'SQLSTATE', 'SQLWARNING',
-                          'SQL_BIG_RESULT', 'SQL_CALC_FOUND_ROWS', 'SQL_SMALL_RESULT',
-                          'SSL', 'STARTING', 'STRAIGHT_JOIN',
-                          'TABLE', 'TERMINATED', 'THEN',
-                          'TINYBLOB', 'TINYINT', 'TINYTEXT',
-                          'TO', 'TRAILING', 'TRIGGER',
-                          'TRUE', 'UNDO', 'UNION',
-                          'UNIQUE', 'UNLOCK', 'UNSIGNED',
-                          'UPDATE', 'USAGE', 'USE',
-                          'USING', 'UTC_DATE', 'UTC_TIME',
-                          'UTC_TIMESTAMP', 'VALUES', 'VARBINARY',
-                          'VARCHAR', 'VARCHARACTER', 'VARYING',
-                          'WHEN', 'WHERE', 'WHILE',
-                          'WITH', 'WRITE', 'X509',
-                          'XOR', 'YEAR_MONTH', 'ZEROFILL'
-                          );
-
-    public function getNativeDeclaration($field)
-    {
-        if ( ! isset($field['type'])) {
-            throw new IPF_ORM_DataDict_Exception('Missing column type.');
-        }
-
-        switch ($field['type']) {
-            case 'char':
-                $length = ( ! empty($field['length'])) ? $field['length'] : false;
-
-                return $length ? 'CHAR('.$length.')' : 'CHAR(255)';
-            case 'varchar':
-            case 'array':
-            case 'object':
-            case 'string':
-            case 'gzip':
-                if ( ! isset($field['length'])) {
-                    if (array_key_exists('default', $field)) {
-                        $field['length'] = $this->conn->varchar_max_length;
-                    } else {
-                        $field['length'] = false;
-                    }
-                }
-
-                $length = ($field['length'] <= $this->conn->varchar_max_length) ? $field['length'] : false;
-                $fixed  = (isset($field['fixed'])) ? $field['fixed'] : false;
-
-                return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
-                    : ($length ? 'VARCHAR(' . $length . ')' : 'TEXT');
-            case 'clob':
-                if ( ! empty($field['length'])) {
-                    $length = $field['length'];
-                    if ($length <= 255) {
-                        return 'TINYTEXT';
-                    } elseif ($length <= 65532) {
-                        return 'TEXT';
-                    } elseif ($length <= 16777215) {
-                        return 'MEDIUMTEXT';
-                    }
-                }
-                return 'LONGTEXT';
-            case 'blob':
-                if ( ! empty($field['length'])) {
-                    $length = $field['length'];
-                    if ($length <= 255) {
-                        return 'TINYBLOB';
-                    } elseif ($length <= 65532) {
-                        return 'BLOB';
-                    } elseif ($length <= 16777215) {
-                        return 'MEDIUMBLOB';
-                    }
-                }
-                return 'LONGBLOB';
-            case 'enum':
-                if ($this->conn->getAttribute(IPF_ORM::ATTR_USE_NATIVE_ENUM)) {
-                    $values = array();
-                    foreach ($field['values'] as $value) {
-                      $values[] = $this->conn->quote($value, 'varchar');
-                    }
-                    return 'ENUM('.implode(', ', $values).')';
-                }
-                // fall back to integer
-            case 'integer':
-            case 'int':
-                if ( ! empty($field['length'])) {
-                    $length = $field['length'];
-                    if ($length <= 1) {
-                        return 'TINYINT';
-                    } elseif ($length == 2) {
-                        return 'SMALLINT';
-                    } elseif ($length == 3) {
-                        return 'MEDIUMINT';
-                    } elseif ($length == 4) {
-                        return 'INT';
-                    } elseif ($length > 4) {
-                        return 'BIGINT';
-                    }
-                }
-                return 'INT';
-            case 'boolean':
-                return 'TINYINT(1)';
-            case 'date':
-                return 'DATE';
-            case 'time':
-                return 'TIME';
-            case 'datetime':
-                return 'DATETIME';
-            case 'timestamp':
-                return 'TIMESTAMP';
-            case 'float':
-            case 'double':
-                return 'DOUBLE';
-            case 'decimal':
-                $scale = !empty($field['scale']) ? $field['scale'] : $this->conn->getAttribute(IPF_ORM::ATTR_DECIMAL_PLACES);
-                if (!empty($field['length'])) {
-                    $length = $field['length'];
-                    if (is_array($length)) {
-                        list($length, $scale) = $length;
-                    }
-                } else {
-                    $length = 18;
-                }
-                return 'DECIMAL('.$length.','.$scale.')';
-            case 'bit':
-                return 'BIT';
-        }
-        throw new IPF_ORM_Exception('Unknown field type \'' . $field['type'] .  '\'.');
-    }
-
-    public function getPortableDeclaration(array $field)
-    {
-        $dbType = strtolower($field['type']);
-        $dbType = strtok($dbType, '(), ');
-        if ($dbType == 'national') {
-            $dbType = strtok('(), ');
-        }
-        if (isset($field['length'])) {
-            $length = $field['length'];
-            $decimal = '';
-        } else {
-            $length = strtok('(), ');
-            $decimal = strtok('(), ');
-        }
-        $type = array();
-        $unsigned = $fixed = null;
-
-        if ( ! isset($field['name'])) {
-            $field['name'] = '';
-        }
-
-        $values = null;
-
-        switch ($dbType) {
-            case 'tinyint':
-                $type[] = 'integer';
-                $type[] = 'boolean';
-                if (preg_match('/^(is|has)/', $field['name'])) {
-                    $type = array_reverse($type);
-                }
-                $unsigned = preg_match('/ unsigned/i', $field['type']);
-                $length = 1;
-            break;
-            case 'smallint':
-                $type[] = 'integer';
-                $unsigned = preg_match('/ unsigned/i', $field['type']);
-                $length = 2;
-            break;
-            case 'mediumint':
-                $type[] = 'integer';
-                $unsigned = preg_match('/ unsigned/i', $field['type']);
-                $length = 3;
-            break;
-            case 'int':
-            case 'integer':
-                $type[] = 'integer';
-                $unsigned = preg_match('/ unsigned/i', $field['type']);
-                $length = 4;
-            break;
-            case 'bigint':
-                $type[] = 'integer';
-                $unsigned = preg_match('/ unsigned/i', $field['type']);
-                $length = 8;
-            break;
-            case 'tinytext':
-            case 'mediumtext':
-            case 'longtext':
-            case 'text':
-            case 'varchar':
-                $fixed = false;
-            case 'string':
-            case 'char':
-                $type[] = 'string';
-                if ($length == '1') {
-                    $type[] = 'boolean';
-                    if (preg_match('/^(is|has)/', $field['name'])) {
-                        $type = array_reverse($type);
-                    }
-                } elseif (strstr($dbType, 'text')) {
-                    $type[] = 'clob';
-                    if ($decimal == 'binary') {
-                        $type[] = 'blob';
-                    }
-                }
-                if ($fixed !== false) {
-                    $fixed = true;
-                }
-            break;
-            case 'enum':
-                $type[] = 'enum';
-                preg_match_all('/\'((?:\'\'|[^\'])*)\'/', $field['type'], $matches);
-                $length = 0;
-                $fixed = false;
-                if (is_array($matches)) {
-                    foreach ($matches[1] as &$value) {
-                        $value = str_replace('\'\'', '\'', $value);
-                        $length = max($length, strlen($value));
-                    }
-                    if ($length == '1' && count($matches[1]) == 2) {
-                        $type[] = 'boolean';
-                        if (preg_match('/^(is|has)/', $field['name'])) {
-                            $type = array_reverse($type);
-                        }
-                    }
-
-                    $values = $matches[1];
-                }
-                $type[] = 'integer';
-                break;
-            case 'set':
-                $fixed = false;
-                $type[] = 'text';
-                $type[] = 'integer';
-            break;
-            case 'date':
-                $type[] = 'date';
-                $length = null;
-            break;
-            case 'datetime':
-            case 'timestamp':
-                $type[] = 'timestamp';
-                $length = null;
-            break;
-            case 'time':
-                $type[] = 'time';
-                $length = null;
-            break;
-            case 'float':
-            case 'double':
-            case 'real':
-                $type[] = 'float';
-                $unsigned = preg_match('/ unsigned/i', $field['type']);
-            break;
-            case 'unknown':
-            case 'decimal':
-            case 'numeric':
-                $type[] = 'decimal';
-                $unsigned = preg_match('/ unsigned/i', $field['type']);
-            break;
-            case 'tinyblob':
-            case 'mediumblob':
-            case 'longblob':
-            case 'blob':
-                $type[] = 'blob';
-                $length = null;
-            break;
-            case 'year':
-                $type[] = 'integer';
-                $type[] = 'date';
-                $length = null;
-            break;
-            case 'bit':
-                $type[] = 'bit';
-            break;
-            default:
-                throw new IPF_ORM_Exception('unknown database attribute type: ' . $dbType);
-        }
-
-        $length = ((int) $length == 0) ? null : (int) $length;
-
-        if ($values === null) {
-            return array('type' => $type, 'length' => $length, 'unsigned' => $unsigned, 'fixed' => $fixed);
-        } else {
-            return array('type' => $type, 'length' => $length, 'unsigned' => $unsigned, 'fixed' => $fixed, 'values' => $values);
-        }
-    }
-
-    public function getIntegerDeclaration($name, $field)
-    {
-        $default = $autoinc = '';
-        if ( ! empty($field['autoincrement'])) {
-            $autoinc = ' AUTO_INCREMENT';
-        } elseif (array_key_exists('default', $field)) {
-            if ($field['default'] === '') {
-                $field['default'] = empty($field['notnull']) ? null : 0;
-            }
-            if (is_null($field['default'])) {
-                $default = ' DEFAULT NULL';
-            } else {
-                $default = ' DEFAULT '.$this->conn->quote($field['default']);
-            }
-        }
-
-        $notnull  = (isset($field['notnull'])  && $field['notnull'])  ? ' NOT NULL' : '';
-        $unsigned = (isset($field['unsigned']) && $field['unsigned']) ? ' UNSIGNED' : '';
-
-        $name = $this->conn->quoteIdentifier($name, true);
-
-        return $name . ' ' . $this->getNativeDeclaration($field) . $unsigned . $default . $notnull . $autoinc;
-    }
-}
-
index 7e62f216becb3140a129c35d8a1c71f82e0bee1b..18b7c94cdd41270ce23b8c179182f42f9744eee8 100644 (file)
@@ -218,28 +218,6 @@ class IPF_ORM_Export extends IPF_ORM_Connection_Module
         return implode(', ', $queryFields);
     }
 
-    public function getDefaultFieldDeclaration($field)
-    {
-        $default = '';
-        if (isset($field['default'])) {
-            if ($field['default'] === '') {
-                $field['default'] = empty($field['notnull'])
-                    ? null : $this->valid_default_values[$field['type']];
-
-                if ($field['default'] === '' &&
-                   ($this->conn->getAttribute(IPF_ORM::ATTR_PORTABILITY) & IPF_ORM::PORTABILITY_EMPTY_TO_NULL)) {
-                    $field['default'] = null;
-                }
-            }
-
-            if ($field['type'] === 'boolean') {
-                $field['default'] = $this->conn->convertBooleans($field['default']);
-            }
-            $default = ' DEFAULT ' . $this->conn->quote($field['default'], $field['type']);
-        }
-        return $default;
-    }
-
     public function getCheckDeclaration(array $definition)
     {
         $constraints = array();
@@ -370,11 +348,6 @@ class IPF_ORM_Export extends IPF_ORM_Connection_Module
         return $sql;
     }
 
-    public function getUniqueFieldDeclaration()
-    {
-        return 'UNIQUE';
-    }
-
     public function exportSortedClassesSql($classes, $groupByConnection = true)
     {
          $connections = array();
index ef9c16e992c1802c35e3ca364231a8538da7beb1..4f61697c9d0980e423ae834ec19236746a00143c 100644 (file)
@@ -115,33 +115,181 @@ class IPF_ORM_Export_Mysql extends IPF_ORM_Export
 
     public function getDeclaration($name, array $field)
     {
-        $default   = $this->getDefaultFieldDeclaration($field);
+        $declaration = $this->conn->quoteIdentifier($name, true) . ' ';
 
-        $charset   = (isset($field['charset']) && $field['charset']) ?
-                    ' CHARACTER SET ' . $field['charset'] : '';
+        if (!isset($field['type']))
+            throw new IPF_ORM_Exception('Missing column type.');
 
-        $collation = (isset($field['collate']) && $field['collate']) ?
-                    ' COLLATE ' . $field['collate'] : '';
+        switch ($field['type']) {
+            case 'char':
+                $length = ( ! empty($field['length'])) ? $field['length'] : false;
 
-        $notnull   = (isset($field['notnull']) && $field['notnull']) ? ' NOT NULL' : '';
+                $declaration .= $length ? 'CHAR('.$length.')' : 'CHAR(255)';
+                break;
+            case 'varchar':
+            case 'array':
+            case 'object':
+            case 'string':
+            case 'gzip':
+                if (!isset($field['length'])) {
+                    if (array_key_exists('default', $field)) {
+                        $field['length'] = $this->conn->varchar_max_length;
+                    } else {
+                        $field['length'] = false;
+                    }
+                }
 
-        $unique    = (isset($field['unique']) && $field['unique']) ?
-                    ' ' . $this->getUniqueFieldDeclaration() : '';
+                $length = ($field['length'] <= $this->conn->varchar_max_length) ? $field['length'] : false;
+                $fixed  = (isset($field['fixed'])) ? $field['fixed'] : false;
+
+                $declaration .= $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
+                    : ($length ? 'VARCHAR(' . $length . ')' : 'TEXT');
+                break;
+            case 'clob':
+                if (!empty($field['length'])) {
+                    $length = $field['length'];
+                    if ($length <= 255) {
+                        return 'TINYTEXT';
+                    } elseif ($length <= 65532) {
+                        return 'TEXT';
+                    } elseif ($length <= 16777215) {
+                        return 'MEDIUMTEXT';
+                    }
+                }
+                $declaration .= 'LONGTEXT';
+                break;
+            case 'blob':
+                if ( ! empty($field['length'])) {
+                    $length = $field['length'];
+                    if ($length <= 255) {
+                        return 'TINYBLOB';
+                    } elseif ($length <= 65532) {
+                        return 'BLOB';
+                    } elseif ($length <= 16777215) {
+                        return 'MEDIUMBLOB';
+                    }
+                }
+                $declaration .= 'LONGBLOB';
+                break;
+            case 'enum':
+                if ($this->conn->getAttribute(IPF_ORM::ATTR_USE_NATIVE_ENUM)) {
+                    $values = array();
+                    foreach ($field['values'] as $value) {
+                      $values[] = $this->conn->quote($value, 'varchar');
+                    }
+                    $declaration .= 'ENUM('.implode(', ', $values).')';
+                    break;
+                }
+                // fall back to integer
+            case 'integer':
+            case 'int':
+                $type = 'INT';
+                if (!empty($field['length'])) {
+                    $length = $field['length'];
+                    if ($length <= 1) {
+                        $type = 'TINYINT';
+                    } elseif ($length == 2) {
+                        $type = 'SMALLINT';
+                    } elseif ($length == 3) {
+                        $type = 'MEDIUMINT';
+                    } elseif ($length == 4) {
+                        $type = 'INT';
+                    } elseif ($length > 4) {
+                        $type = 'BIGINT';
+                    }
+                }
+                $declaration .= $type;
+                if (isset($field['unsigned']) && $field['unsigned'])
+                    $declaration .= ' UNSIGNED';
+                break;
+            case 'boolean':
+                $declaration .= 'TINYINT(1)';
+                break;
+            case 'date':
+                $declaration .= 'DATE';
+                break;
+            case 'time':
+                $declaration .= 'TIME';
+                break;
+            case 'datetime':
+                $declaration .= 'DATETIME';
+                break;
+            case 'timestamp':
+                $declaration .= 'TIMESTAMP';
+                break;
+            case 'float':
+            case 'double':
+                $declaration .= 'DOUBLE';
+                break;
+            case 'decimal':
+                $scale = !empty($field['scale']) ? $field['scale'] : $this->conn->getAttribute(IPF_ORM::ATTR_DECIMAL_PLACES);
+                if (!empty($field['length'])) {
+                    $length = $field['length'];
+                    if (is_array($length)) {
+                        list($length, $scale) = $length;
+                    }
+                } else {
+                    $length = 18;
+                }
+                $declaration .= 'DECIMAL('.$length.','.$scale.')';
+                break;
+            case 'bit':
+                $declaration .= 'BIT';
+                break;
+            default:
+                throw new IPF_ORM_Exception('Unknown field type \'' . $field['type'] .  '\'.');
+        }
 
-        $check     = (isset($field['check']) && $field['check']) ?
-                    ' ' . $field['check'] : '';
+        if (isset($field['charset']) && $field['charset'])
+            $declaration .= ' CHARACTER SET ' . $field['charset'];
 
-        $comment   = (isset($field['comment']) && $field['comment']) ?
-                    " COMMENT '" . $field['comment'] . "'" : '';
+        if (isset($field['collate']) && $field['collate'])
+            $declaration .= ' COLLATE ' . $field['collate'];
 
-        $method = 'get' . $field['type'] . 'Declaration';
+        if (isset($field['notnull']) && $field['notnull'])
+            $declaration .= ' NOT NULL';
 
-        if (method_exists($this->conn->dataDict, $method)) {
-            return $this->conn->dataDict->$method($name, $field);
+        if (!empty($field['autoincrement'])) {
+            $declaration .= ' AUTO_INCREMENT';
         } else {
-            $dec = $this->conn->dataDict->getNativeDeclaration($field);
+            $declaration .= $this->getDefaultFieldDeclaration($field);
+
+            if (isset($field['unique']) && $field['unique'])
+                $declaration .= ' UNIQUE';
+        }
+
+        if (isset($field['comment']) && $field['comment'])
+            $declaration .= ' COMMENT ' . $this->conn->quote($field['comment'], 'varchar');
+
+        return $declaration;
+    }
+
+    private function getDefaultFieldDeclaration($field)
+    {
+        $default = '';
+        if (isset($field['default']) && (!isset($field['length']) || $field['length'] <= 255)) {
+            if ($field['default'] === '') {
+                $field['default'] = empty($field['notnull']) ? null : $this->valid_default_values[$field['type']];
+            }
+
+            if ($field['default'] === '' && ($this->conn->getAttribute(IPF_ORM::ATTR_PORTABILITY) & IPF_ORM::PORTABILITY_EMPTY_TO_NULL))
+                $field['default'] = null;
+
+            if (is_null($field['default'])) {
+                $default = ' DEFAULT NULL';
+            } else {
+                if ($field['type'] === 'boolean') {
+                    $fieldType = 'boolean';
+                    $field['default'] = $this->conn->convertBooleans($field['default']);
+                } elseif ($field['type'] == 'enum' && $this->conn->getAttribute(IPF_ORM::ATTR_USE_NATIVE_ENUM)) {
+                    $fieldType = 'varchar';
+                } else {
+                    $fieldType = $field['type'];
+                }
+                $default = ' DEFAULT ' . $this->conn->quote($field['default'], $fieldType);
+            }
         }
-        return $this->conn->quoteIdentifier($name, true) . ' ' . $dec . $charset . $default . $notnull . $comment . $unique . $check . $collation;
+        return $default;
     }
 
     public function alterTableSql($name, array $changes, $check = false)
@@ -258,34 +406,6 @@ class IPF_ORM_Export_Mysql extends IPF_ORM_Export
         return $query;
     }
 
-    public function getDefaultFieldDeclaration($field)
-    {
-        $default = '';
-        if (isset($field['default']) && ( ! isset($field['length']) || $field['length'] <= 255)) {
-            if ($field['default'] === '') {
-                $field['default'] = empty($field['notnull'])
-                    ? null : $this->valid_default_values[$field['type']];
-
-                if ($field['default'] === ''
-                    && ($this->conn->getAttribute(IPF_ORM::ATTR_PORTABILITY) & IPF_ORM::PORTABILITY_EMPTY_TO_NULL)
-                ) {
-                    $field['default'] = ' ';
-                }
-            }
-    
-            // Proposed patch:
-            if ($field['type'] == 'enum' && $this->conn->getAttribute(IPF_ORM::ATTR_USE_NATIVE_ENUM)) {
-                $fieldType = 'varchar';
-            } else {
-                $fieldType = $field['type'];
-            }
-            
-            $default = ' DEFAULT ' . $this->conn->quote($field['default'], $fieldType);
-            //$default = ' DEFAULT ' . $this->conn->quote($field['default'], $field['type']);
-        }
-        return $default;
-    }
-
     public function getIndexDeclaration($name, array $definition)
     {
         $name   = $this->conn->formatter->getIndexName($name);
@@ -382,3 +502,4 @@ class IPF_ORM_Export_Mysql extends IPF_ORM_Export
         return $this->conn->exec('ALTER TABLE ' . $table . ' DROP FOREIGN KEY ' . $name);
     }
 }
+