mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2024-11-15 11:28:25 +00:00
Implementation of table level and field level parameters support
This commit is contained in:
parent
86d0a04c8d
commit
627eff5f24
4 changed files with 208 additions and 7 deletions
|
@ -237,6 +237,7 @@ class CakeSchema extends Object {
|
||||||
if (empty($tables[$Object->table])) {
|
if (empty($tables[$Object->table])) {
|
||||||
$tables[$Object->table] = $this->__columns($Object);
|
$tables[$Object->table] = $this->__columns($Object);
|
||||||
$tables[$Object->table]['indexes'] = $db->index($Object);
|
$tables[$Object->table]['indexes'] = $db->index($Object);
|
||||||
|
$tables[$Object->table]['tableParameters'] = $db->readTableParameters($table);
|
||||||
unset($currentTables[$key]);
|
unset($currentTables[$key]);
|
||||||
}
|
}
|
||||||
if (!empty($Object->hasAndBelongsToMany)) {
|
if (!empty($Object->hasAndBelongsToMany)) {
|
||||||
|
@ -250,6 +251,7 @@ class CakeSchema extends Object {
|
||||||
$key = array_search($table, $currentTables);
|
$key = array_search($table, $currentTables);
|
||||||
$tables[$Object->$class->table] = $this->__columns($Object->$class);
|
$tables[$Object->$class->table] = $this->__columns($Object->$class);
|
||||||
$tables[$Object->$class->table]['indexes'] = $db->index($Object->$class);
|
$tables[$Object->$class->table]['indexes'] = $db->index($Object->$class);
|
||||||
|
$tables[$Object->$class->table]['tableParameters'] = $db->readTableParameters($table);
|
||||||
unset($currentTables[$key]);
|
unset($currentTables[$key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -279,12 +281,15 @@ class CakeSchema extends Object {
|
||||||
if (in_array($table, $systemTables)) {
|
if (in_array($table, $systemTables)) {
|
||||||
$tables[$Object->table] = $this->__columns($Object);
|
$tables[$Object->table] = $this->__columns($Object);
|
||||||
$tables[$Object->table]['indexes'] = $db->index($Object);
|
$tables[$Object->table]['indexes'] = $db->index($Object);
|
||||||
|
$tables[$Object->table]['tableParameters'] = $db->readTableParameters($table);
|
||||||
} elseif ($models === false) {
|
} elseif ($models === false) {
|
||||||
$tables[$table] = $this->__columns($Object);
|
$tables[$table] = $this->__columns($Object);
|
||||||
$tables[$table]['indexes'] = $db->index($Object);
|
$tables[$table]['indexes'] = $db->index($Object);
|
||||||
|
$tables[$table]['tableParameters'] = $db->readTableParameters($table);
|
||||||
} else {
|
} else {
|
||||||
$tables['missing'][$table] = $this->__columns($Object);
|
$tables['missing'][$table] = $this->__columns($Object);
|
||||||
$tables['missing'][$table]['indexes'] = $db->index($Object);
|
$tables['missing'][$table]['indexes'] = $db->index($Object);
|
||||||
|
$tables['missing'][$table]['tableParameters'] = $db->readTableParameters($table);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,30 @@ class DboMysqlBase extends DboSource {
|
||||||
'rollback' => 'ROLLBACK'
|
'rollback' => 'ROLLBACK'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of engine specific additional field parameters used on table creating
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
var $fieldParameters = array(
|
||||||
|
'charset' => array('value' => 'CHARACTER SET', 'quote' => false, 'join' => ' ', 'column' => false, 'position' => 'beforeDefault'),
|
||||||
|
'collate' => array('value' => 'COLLATE', 'quote' => false, 'join' => ' ', 'column' => 'Collation', 'position' => 'beforeDefault'),
|
||||||
|
'comment' => array('value' => 'COMMENT', 'quote' => true, 'join' => ' ', 'column' => 'Comment', 'position' => 'afterDefault')
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of table engine specific parameters used on table creating
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
var $tableParameters = array(
|
||||||
|
'charset' => array('value' => 'DEFAULT CHARSET', 'quote' => false, 'join' => '=', 'column' => 'charset'),
|
||||||
|
'collate' => array('value' => 'COLLATE', 'quote' => false, 'join' => '=', 'column' => 'Collation'),
|
||||||
|
'engine' => array('value' => 'ENGINE', 'quote' => false, 'join' => '=', 'column' => 'Engine')
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MySQL column definition
|
* MySQL column definition
|
||||||
*
|
*
|
||||||
|
@ -457,6 +481,38 @@ class DboMysql extends DboMysqlBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an detailed array of sources (tables) in the database.
|
||||||
|
*
|
||||||
|
* @param string $name Table name to get parameters
|
||||||
|
* @return array Array of tablenames in the database
|
||||||
|
*/
|
||||||
|
function listDetailedSources($name = null) {
|
||||||
|
$condition = '';
|
||||||
|
if (is_string($name)) {
|
||||||
|
$condition = ' WHERE Name=' . $this->value($name);
|
||||||
|
}
|
||||||
|
$result = $this->query('SHOW TABLE STATUS FROM ' . $this->name($this->config['database']) . $condition . ';');
|
||||||
|
if (!$result) {
|
||||||
|
return array();
|
||||||
|
} else {
|
||||||
|
$tables = array();
|
||||||
|
foreach ($result as $row) {
|
||||||
|
$tables[$row['TABLES']['Name']] = $row['TABLES'];
|
||||||
|
if (!empty($row['TABLES']['Collation'])) {
|
||||||
|
$charset = $this->getCharsetName($row['TABLES']['Collation']);
|
||||||
|
if ($charset) {
|
||||||
|
$tables[$row['TABLES']['Name']]['charset'] = $charset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_string($name)) {
|
||||||
|
return $tables[$name];
|
||||||
|
}
|
||||||
|
return $tables;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of the fields in given table name.
|
* Returns an array of the fields in given table name.
|
||||||
*
|
*
|
||||||
|
@ -469,7 +525,7 @@ class DboMysql extends DboMysqlBase {
|
||||||
return $cache;
|
return $cache;
|
||||||
}
|
}
|
||||||
$fields = false;
|
$fields = false;
|
||||||
$cols = $this->query('DESCRIBE ' . $this->fullTableName($model));
|
$cols = $this->query('SHOW FULL COLUMNS FROM ' . $this->fullTableName($model));
|
||||||
|
|
||||||
foreach ($cols as $column) {
|
foreach ($cols as $column) {
|
||||||
$colKey = array_keys($column);
|
$colKey = array_keys($column);
|
||||||
|
@ -486,12 +542,37 @@ class DboMysql extends DboMysqlBase {
|
||||||
if (!empty($column[0]['Key']) && isset($this->index[$column[0]['Key']])) {
|
if (!empty($column[0]['Key']) && isset($this->index[$column[0]['Key']])) {
|
||||||
$fields[$column[0]['Field']]['key'] = $this->index[$column[0]['Key']];
|
$fields[$column[0]['Field']]['key'] = $this->index[$column[0]['Key']];
|
||||||
}
|
}
|
||||||
|
foreach ($this->fieldParameters as $name => $value) {
|
||||||
|
if (!empty($column[0][$value['column']])) {
|
||||||
|
$fields[$column[0]['Field']][$name] = $column[0][$value['column']];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isset($fields[$column[0]['Field']]['collate'])) {
|
||||||
|
$charset = $this->getCharsetName($fields[$column[0]['Field']]['collate']);
|
||||||
|
if ($charset) {
|
||||||
|
$fields[$column[0]['Field']]['charset'] = $charset;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->__cacheDescription($this->fullTableName($model, false), $fields);
|
$this->__cacheDescription($this->fullTableName($model, false), $fields);
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query charset by collation
|
||||||
|
*
|
||||||
|
* @param string $name Collation name
|
||||||
|
* @return string Character set name
|
||||||
|
*/
|
||||||
|
function getCharsetName($name) {
|
||||||
|
$cols = $this->query('SELECT CHARACTER_SET_NAME FROM INFORMATION_SCHEMA.COLLATIONS WHERE COLLATION_NAME= ' . $this->value($name) . ';');
|
||||||
|
if (isset($cols[0]['COLLATIONS']['CHARACTER_SET_NAME'])) {
|
||||||
|
return $cols[0]['COLLATIONS']['CHARACTER_SET_NAME'];
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a quoted and escaped string of $data for use in an SQL statement.
|
* Returns a quoted and escaped string of $data for use in an SQL statement.
|
||||||
*
|
*
|
||||||
|
|
|
@ -91,6 +91,22 @@ class DboSource extends DataSource {
|
||||||
'rollback' => 'ROLLBACK'
|
'rollback' => 'ROLLBACK'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of table engine specific parameters used on table creating
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
var $tableParameters = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of engine specific additional field parameters used on table creating
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
var $fieldParameters = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
|
@ -1370,15 +1386,17 @@ class DboSource extends DataSource {
|
||||||
return "DELETE {$alias} FROM {$table} {$aliases}{$conditions}";
|
return "DELETE {$alias} FROM {$table} {$aliases}{$conditions}";
|
||||||
break;
|
break;
|
||||||
case 'schema':
|
case 'schema':
|
||||||
foreach (array('columns', 'indexes') as $var) {
|
foreach (array('columns', 'indexes', 'tableParameters') as $var) {
|
||||||
if (is_array(${$var})) {
|
if (is_array(${$var})) {
|
||||||
${$var} = "\t" . join(",\n\t", array_filter(${$var}));
|
${$var} = "\t" . join(",\n\t", array_filter(${$var}));
|
||||||
|
} else {
|
||||||
|
${$var} = '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (trim($indexes) != '') {
|
if (trim($indexes) != '') {
|
||||||
$columns .= ',';
|
$columns .= ',';
|
||||||
}
|
}
|
||||||
return "CREATE TABLE {$table} (\n{$columns}{$indexes});";
|
return "CREATE TABLE {$table} (\n{$columns}{$indexes}){$tableParameters};";
|
||||||
break;
|
break;
|
||||||
case 'alter':
|
case 'alter':
|
||||||
break;
|
break;
|
||||||
|
@ -2334,7 +2352,7 @@ class DboSource extends DataSource {
|
||||||
|
|
||||||
foreach ($schema->tables as $curTable => $columns) {
|
foreach ($schema->tables as $curTable => $columns) {
|
||||||
if (!$tableName || $tableName == $curTable) {
|
if (!$tableName || $tableName == $curTable) {
|
||||||
$cols = $colList = $indexes = array();
|
$cols = $colList = $indexes = $tableParameters = array();
|
||||||
$primary = null;
|
$primary = null;
|
||||||
$table = $this->fullTableName($curTable);
|
$table = $this->fullTableName($curTable);
|
||||||
|
|
||||||
|
@ -2345,14 +2363,16 @@ class DboSource extends DataSource {
|
||||||
if (isset($col['key']) && $col['key'] == 'primary') {
|
if (isset($col['key']) && $col['key'] == 'primary') {
|
||||||
$primary = $name;
|
$primary = $name;
|
||||||
}
|
}
|
||||||
if ($name !== 'indexes') {
|
if ($name !== 'indexes' && $name !== 'tableParameters') {
|
||||||
$col['name'] = $name;
|
$col['name'] = $name;
|
||||||
if (!isset($col['type'])) {
|
if (!isset($col['type'])) {
|
||||||
$col['type'] = 'string';
|
$col['type'] = 'string';
|
||||||
}
|
}
|
||||||
$cols[] = $this->buildColumn($col);
|
$cols[] = $this->buildColumn($col);
|
||||||
} else {
|
} elseif ($name == 'indexes') {
|
||||||
$indexes = array_merge($indexes, $this->buildIndex($col, $table));
|
$indexes = array_merge($indexes, $this->buildIndex($col, $table));
|
||||||
|
} elseif ($name == 'tableParameters') {
|
||||||
|
$tableParameters = array_merge($tableParameters, $this->buildTableParameters($col, $table));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (empty($indexes) && !empty($primary)) {
|
if (empty($indexes) && !empty($primary)) {
|
||||||
|
@ -2360,7 +2380,7 @@ class DboSource extends DataSource {
|
||||||
$indexes = array_merge($indexes, $this->buildIndex($col, $table));
|
$indexes = array_merge($indexes, $this->buildIndex($col, $table));
|
||||||
}
|
}
|
||||||
$columns = $cols;
|
$columns = $cols;
|
||||||
$out .= $this->renderStatement('schema', compact('table', 'columns', 'indexes')) . "\n\n";
|
$out .= $this->renderStatement('schema', compact('table', 'columns', 'indexes', 'tableParameters')) . "\n\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $out;
|
return $out;
|
||||||
|
@ -2440,6 +2460,16 @@ class DboSource extends DataSource {
|
||||||
$column['default'] = null;
|
$column['default'] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach ($this->fieldParameters as $paramName => $value) {
|
||||||
|
if (isset($column[$paramName]) && $value['position'] == 'beforeDefault') {
|
||||||
|
$val = $column[$paramName];
|
||||||
|
if ($value['quote']) {
|
||||||
|
$val = $this->value($val);
|
||||||
|
}
|
||||||
|
$out .= ' ' . $value['value'] . $value['join'] . $val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isset($column['key']) && $column['key'] == 'primary' && $type == 'integer') {
|
if (isset($column['key']) && $column['key'] == 'primary' && $type == 'integer') {
|
||||||
$out .= ' ' . $this->columns['primary_key']['name'];
|
$out .= ' ' . $this->columns['primary_key']['name'];
|
||||||
} elseif (isset($column['key']) && $column['key'] == 'primary') {
|
} elseif (isset($column['key']) && $column['key'] == 'primary') {
|
||||||
|
@ -2453,6 +2483,17 @@ class DboSource extends DataSource {
|
||||||
} elseif (isset($column['null']) && $column['null'] == false) {
|
} elseif (isset($column['null']) && $column['null'] == false) {
|
||||||
$out .= ' NOT NULL';
|
$out .= ' NOT NULL';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach ($this->fieldParameters as $paramName => $value) {
|
||||||
|
if (isset($column[$paramName]) && $value['position'] == 'afterDefault') {
|
||||||
|
$val = $column[$paramName];
|
||||||
|
if ($value['quote']) {
|
||||||
|
$val = $this->value($val);
|
||||||
|
}
|
||||||
|
$out .= ' ' . $value['value'] . $value['join'] . $val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $out;
|
return $out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2486,6 +2527,46 @@ class DboSource extends DataSource {
|
||||||
return $join;
|
return $join;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read additional table parameters
|
||||||
|
*
|
||||||
|
* @param array $parameters
|
||||||
|
* @param string $table
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function readTableParameters($name) {
|
||||||
|
$parameters = array();
|
||||||
|
if ($this->isInterfaceSupported('listDetailedSources')) {
|
||||||
|
$currentTableDetails = $this->listDetailedSources($name);
|
||||||
|
foreach ($this->tableParameters as $paramName => $parameter) {
|
||||||
|
if (!empty($parameter['column']) && !empty($currentTableDetails[$parameter['column']])) {
|
||||||
|
$parameters[$paramName] = $currentTableDetails[$parameter['column']];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format parameters for create table
|
||||||
|
*
|
||||||
|
* @param array $parameters
|
||||||
|
* @param string $table
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function buildTableParameters($parameters, $table = null) {
|
||||||
|
$result = array();
|
||||||
|
foreach ($parameters as $name => $value) {
|
||||||
|
if (isset($this->tableParameters[$name])) {
|
||||||
|
if ($this->tableParameters[$name]['quote']) {
|
||||||
|
$value = $this->value($value);
|
||||||
|
}
|
||||||
|
$result[] = $this->tableParameters[$name]['value'] . $this->tableParameters[$name]['join'] . $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Guesses the data type of an array
|
* Guesses the data type of an array
|
||||||
*
|
*
|
||||||
|
|
|
@ -385,6 +385,40 @@ class DboMysqlTest extends CakeTestCase {
|
||||||
$this->db->query('DROP TABLE ' . $name);
|
$this->db->query('DROP TABLE ' . $name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* testBuildColumn method
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function testBuildColumn() {
|
||||||
|
$this->db->columns = array('varchar(255)' => 1);
|
||||||
|
$data = array(
|
||||||
|
'name' => 'testName',
|
||||||
|
'type' => 'varchar(255)',
|
||||||
|
'default',
|
||||||
|
'null' => true,
|
||||||
|
'key',
|
||||||
|
'comment' => 'test'
|
||||||
|
);
|
||||||
|
$result = $this->db->buildColumn($data);
|
||||||
|
$expected = '`testName` DEFAULT NULL COMMENT \'test\'';
|
||||||
|
$this->assertEqual($result, $expected);
|
||||||
|
|
||||||
|
$data = array(
|
||||||
|
'name' => 'testName',
|
||||||
|
'type' => 'varchar(255)',
|
||||||
|
'default',
|
||||||
|
'null' => true,
|
||||||
|
'key',
|
||||||
|
'charset' => 'utf8',
|
||||||
|
'collate' => 'utf8_unicode_ci'
|
||||||
|
);
|
||||||
|
$result = $this->db->buildColumn($data);
|
||||||
|
$expected = '`testName` CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL';
|
||||||
|
$this->assertEqual($result, $expected);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MySQL 4.x returns index data in a different format,
|
* MySQL 4.x returns index data in a different format,
|
||||||
* Using a mock ensure that MySQL 4.x output is properly parsed.
|
* Using a mock ensure that MySQL 4.x output is properly parsed.
|
||||||
|
|
Loading…
Reference in a new issue