Skip to content

Commit

Permalink
Merge pull request #9550 from cakephp/issue-9526
Browse files Browse the repository at this point in the history
Fix enum column length detection.
  • Loading branch information
lorenzo committed Oct 6, 2016
2 parents 3afbd25 + 9c3b17c commit 9425234
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 42 deletions.
13 changes: 4 additions & 9 deletions lib/Cake/Model/Datasource/Database/Postgres.php
Expand Up @@ -727,19 +727,14 @@ public function column($real) {
* @return int An integer representing the length of the column
*/
public function length($real) {
$col = str_replace(array(')', 'unsigned'), '', $real);
$limit = null;

if (strpos($col, '(') !== false) {
list($col, $limit) = explode('(', $col);
$col = $real;
if (strpos($real, '(') !== false) {
list($col, $limit) = explode('(', $real);
}
if ($col === 'uuid') {
return 36;
}
if ($limit) {
return (int)$limit;
}
return null;
return parent::length($real);
}

/**
Expand Down
57 changes: 24 additions & 33 deletions lib/Cake/Model/Datasource/DboSource.php
Expand Up @@ -3097,54 +3097,45 @@ public function hasAny(Model $Model, $sql) {
* @return mixed An integer or string representing the length of the column, or null for unknown length.
*/
public function length($real) {
if (!preg_match_all('/([\w\s]+)(?:\((\d+)(?:,(\d+))?\))?(\sunsigned)?(\szerofill)?/', $real, $result)) {
$col = str_replace(array(')', 'unsigned'), '', $real);
$limit = null;

if (strpos($col, '(') !== false) {
list($col, $limit) = explode('(', $col);
}
if ($limit !== null) {
return (int)$limit;
}
return null;
}

preg_match('/([\w\s]+)(?:\((.+?)\))?(\sunsigned)?/i', $real, $result);
$types = array(
'int' => 1, 'tinyint' => 1, 'smallint' => 1, 'mediumint' => 1, 'integer' => 1, 'bigint' => 1
);

list($real, $type, $length, $offset, $sign) = $result;
$typeArr = $type;
$type = $type[0];
$length = $length[0];
$offset = $offset[0];
$type = $length = null;
if (isset($result[1])) {
$type = $result[1];
}
if (isset($result[2])) {
$length = $result[2];
}
$sign = isset($result[3]);

$isFloat = in_array($type, array('dec', 'decimal', 'float', 'numeric', 'double'));
if ($isFloat && $offset) {
return $length . ',' . $offset;
if ($isFloat && strpos($length, ',') !== false) {
return $length;
}

if (($real[0] == $type) && (count($real) === 1)) {
if ($length === null) {
return null;
}

if (isset($types[$type])) {
$length += $types[$type];
if (!empty($sign)) {
$length--;
}
} elseif (in_array($type, array('enum', 'set'))) {
$length = 0;
foreach ($typeArr as $key => $enumValue) {
if ($key === 0) {
continue;
}
return (int)$length;
}
if (in_array($type, array('enum', 'set'))) {
$values = array_map(function ($value) {
return trim(trim($value), '\'"');
}, explode(',', $length));

$maxLength = 0;
foreach ($values as $key => $enumValue) {
$tmpLength = strlen($enumValue);
if ($tmpLength > $length) {
$length = $tmpLength;
if ($tmpLength > $maxLength) {
$maxLength = $tmpLength;
}
}
return $maxLength;
}
return (int)$length;
}
Expand Down
31 changes: 31 additions & 0 deletions lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php
Expand Up @@ -1826,4 +1826,35 @@ public function testFlushQueryCache() {
$this->db->flushQueryCache();
$this->assertAttributeCount(0, '_queryCache', $this->db);
}

/**
* Test length parsing.
*
* @return void
*/
public function testLength() {
$result = $this->db->length('varchar(255)');
$this->assertEquals(255, $result);

$result = $this->db->length('integer(11)');
$this->assertEquals(11, $result);

$result = $this->db->length('integer unsigned');
$this->assertNull($result);

$result = $this->db->length('integer(11) unsigned');
$this->assertEquals(11, $result);

$result = $this->db->length('integer(11) zerofill');
$this->assertEquals(11, $result);

$result = $this->db->length('decimal(20,3)');
$this->assertEquals('20,3', $result);

$result = $this->db->length('enum("one", "longer")');
$this->assertEquals(6, $result);

$result = $this->db->length("enum('One Value','ANOTHER ... VALUE ...')");
$this->assertEquals(21, $result);
}
}

0 comments on commit 9425234

Please sign in to comment.