allow data sources to provide smaller integers based on storage requirements

This commit is contained in:
Sebastien Barre 2017-03-03 21:42:58 -05:00 committed by Sebastien Barre
parent 25d746f712
commit d01f3e8aed
3 changed files with 122 additions and 5 deletions

View file

@ -117,6 +117,10 @@ class Mysql extends DboSource {
'text' => array('name' => 'text'),
'biginteger' => array('name' => 'bigint', 'limit' => '20'),
'integer' => array('name' => 'int', 'limit' => '11', 'formatter' => 'intval'),
'integer/4' => array('name' => 'int', 'limit' => '11', 'formatter' => 'intval'),
'integer/3' => array('name' => 'mediumint', 'limit' => '9', 'formatter' => 'intval'),
'integer/2' => array('name' => 'smallint', 'limit' => '6', 'formatter' => 'intval'),
'integer/1' => array('name' => 'tinyint', 'limit' => '4', 'formatter' => 'intval'),
'float' => array('name' => 'float', 'formatter' => 'floatval'),
'decimal' => array('name' => 'decimal', 'formatter' => 'floatval'),
'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
@ -369,6 +373,10 @@ class Mysql extends DboSource {
$fields[$column->Field]['charset'] = $charset;
}
}
$storage = $this->storageRequirement($column->Type);
if (is_numeric($storage)) {
$fields[$column->Field]['storage'] = $storage;
}
}
$this->_cacheDescription($key, $fields);
$cols->closeCursor();
@ -810,6 +818,36 @@ class Mysql extends DboSource {
return 'text';
}
/**
* Gets the storage requirement of a database-native column description, or null if unknown or N/A
*
* @param string $real Real database-layer column type (i.e. "varchar(255)")
* @return mixed An integer representing the storage requirement of the column in bytes, or null if unknown or N/A.
*/
public function storageRequirement($real) {
if (is_array($real)) {
$col = $real['name'];
} else {
$col = $real;
if (strpos($col, '(') !== false) {
list($col, $vals) = explode('(', $col);
}
}
// Base on Storage Requirements for Numeric Types
// https://dev.mysql.com/doc/refman/5.7/en/storage-requirements.html
if ($col === 'tinyint') {
return 1;
}
if ($col === 'smallint') {
return 2;
}
if ($col === 'mediumint') {
return 3;
}
return null;
}
/**
* {@inheritDoc}
*/

View file

@ -3246,6 +3246,16 @@ class DboSource extends DataSource {
return (int)$length;
}
/**
* Gets the storage requirement of a database-native column description, or null if unknown or N/A
*
* @param string $real Real database-layer column type (i.e. "varchar(255)")
* @return mixed An integer representing the storage requirement of the column in bytes, or null if unknown or N/A.
*/
public function storageRequirement($real) {
return null;
}
/**
* Translates between PHP boolean values and Database (faked) boolean values
*
@ -3459,12 +3469,16 @@ class DboSource extends DataSource {
return null;
}
if (!isset($this->columns[$type])) {
trigger_error(__d('cake_dev', 'Column type %s does not exist', $type), E_USER_WARNING);
return null;
// if a storage requirement in bytes was set, try it first (i.e. 'integer/4' before 'integer')
if (isset($storage) && isset($this->columns[$type . '/' . $storage])) {
$real = $this->columns[$type . '/' . $storage];
} else {
if (!isset($this->columns[$type])) {
trigger_error(__d('cake_dev', 'Column type %s does not exist', $type), E_USER_WARNING);
return null;
}
$real = $this->columns[$type];
}
$real = $this->columns[$type];
$out = $this->name($name) . ' ' . $real['name'];
if (isset($column['length'])) {