Refactoring schema generation, passing model tests with SQLite driver, refactoring database methods

git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@5909 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
nate 2007-10-27 20:32:19 +00:00
parent ae9cdb78f4
commit a87a0e2a68
7 changed files with 231 additions and 157 deletions

View file

@ -38,20 +38,20 @@ class TreeBehavior extends ModelBehavior {
function setup(&$model, $config = array()) {
$settings = am(array(
'parent' => 'parent_id',
'left' => 'lft',
'right' => 'rght',
'scope' => '1 = 1',
'enabled' => true,
'type' => 'nested',
'__parentChange' => false
'parent' => 'parent_id',
'left' => 'lft',
'right' => 'rght',
'scope' => '1 = 1',
'enabled' => true,
'type' => 'nested',
'__parentChange' => false
), $config);
/*if (in_array($settings['scope'], $model->getAssociated('belongsTo'))) {
$data = $model->getAssociated($settings['scope']);
$parent =& $model->{$data['className']};
$settings['scope'] = $model->escapeField($data['foreignKey']) . ' = ' . $parent->escapeField($parent->primaryKey, $settings['scope']);
}*/
}*/
$this->settings[$model->alias] = $settings;
}
/**

View file

@ -375,25 +375,6 @@ class DboMysql extends DboSource {
}
return 'text';
}
/**
* Gets the length of a database-native column description, or null if no length
*
* @param string $real Real database-layer column type (i.e. "varchar(255)")
* @return integer An integer representing the length of the column
*/
function length($real) {
$col = r(array(')', 'unsigned'), '', $real);
$limit = null;
if (strpos($col, '(') !== false) {
list($col, $limit) = explode('(', $col);
}
if ($limit != null) {
return intval($limit);
}
return null;
}
/**
* Enter description here...
*
@ -479,52 +460,6 @@ class DboMysql extends DboSource {
}
return $index;
}
/**
* Generate a MySQL schema for the given Schema object
*
* @param object $schema An instance of a subclass of CakeSchema
* @param string $table Optional. If specified only the table name given will be generated.
* Otherwise, all tables defined in the schema are generated.
* @return string
*/
function createSchema($schema, $table = null) {
if (!is_a($schema, 'CakeSchema')) {
trigger_error(__('Invalid schema object', true), E_USER_WARNING);
return null;
}
$out = '';
foreach ($schema->tables as $curTable => $columns) {
if (!$table || $table == $curTable) {
$out .= 'CREATE TABLE ' . $this->fullTableName($curTable) . " (\n";
$cols = $colList = $index = array();
$primary = null;
foreach ($columns as $name => $col) {
if (is_string($col)) {
$col = array('type' => $col);
}
if (isset($col['key']) && $col['key'] == 'primary') {
$primary = $name;
}
if($name !== 'indexes') {
$col['name'] = $name;
if(!isset($col['type'])) {
$col['type'] = 'string';
}
$cols[] = $this->buildColumn($col);
} else {
$index[] = $this->buildIndex($col);
}
}
if(empty($index) && !empty($primary)) {
$col = array('PRIMARY' => array('column'=> $primary, 'unique' => 1));
$index[] = $this->buildIndex($col);
}
$out .= "\t" . join(",\n\t", $cols) . ",\n\t". join(",\n\t", $index) . "\n);\n\n";
}
}
return $out;
}
/**
* Generate a MySQL Alter Table syntax for the given Schema comparison
*
@ -574,7 +509,7 @@ class DboMysql extends DboSource {
return $out;
}
/**
* Generate a MySQL Drop table for the given Schema object
* Generate a MySQL "drop table" statement for the given Schema object
*
* @param object $schema An instance of a subclass of CakeSchema
* @param string $table Optional. If specified only the table name given will be generated.
@ -595,59 +530,6 @@ class DboMysql extends DboSource {
return $out;
}
/**
* Generate a MySQL-native column schema string
*
* @param array $column An array structured like the following: array('name'=>'value', 'type'=>'value'[, options]),
* where options can be 'default', 'length', or 'key'.
* @return string
*/
function buildColumn($column) {
$name = $type = null;
$column = am(array('null' => true), $column);
extract($column);
if (empty($name) || empty($type)) {
trigger_error('Column name or type not defined in schema', E_USER_WARNING);
return null;
}
if (!isset($this->columns[$type])) {
trigger_error("Column type {$type} does not exist", E_USER_WARNING);
return null;
}
$real = $this->columns[$type];
$out = $this->name($name) . ' ' . $real['name'];
if (isset($real['limit']) || isset($real['length']) || isset($column['limit']) || isset($column['length'])) {
if (isset($column['length'])) {
$length = $column['length'];
} elseif (isset($column['limit'])) {
$length = $column['limit'];
} elseif (isset($real['length'])) {
$length = $real['length'];
} else {
$length = $real['limit'];
}
$out .= '(' . $length . ')';
}
if (isset($column['key']) && $column['key'] == 'primary' && (isset($column['extra']) && $column['extra'] == 'auto_increment')) {
$out .= ' NOT NULL AUTO_INCREMENT';
} elseif (isset($column['key']) && $column['key'] == 'primary') {
$out .= ' NOT NULL';
} elseif (isset($column['default']) && isset($column['null']) && $column['null'] == false) {
$out .= ' DEFAULT ' . $this->value($column['default'], $type) . ' NOT NULL';
} elseif (isset($column['default'])) {
$out .= ' DEFAULT ' . $this->value($column['default'], $type);
} elseif (isset($column['null']) && $column['null'] == true) {
$out .= ' DEFAULT NULL';
} elseif (isset($column['null']) && $column['null'] == false) {
$out .= ' NOT NULL';
}
return $out;
}
/**
* Format indexes for create table
*
* @param array $indexes

View file

@ -161,10 +161,21 @@ class DboSqlite extends DboSource {
foreach ($result as $column) {
$fields[$column[0]['name']] = array(
'type' => $this->column($column[0]['type']),
'null' => ! $column[0]['notnull'],
'default' => $column[0]['dflt_value']
'type' => $this->column($column[0]['type']),
'null' => !$column[0]['notnull'],
'default' => $column[0]['dflt_value'],
'length' => $this->length($column[0]['type'])
);
if($column[0]['pk'] == 1) {
$fields[$column[0]['name']] = array(
'type' => $fields[$column[0]['name']]['type'],
'null' => false,
'default' => $column[0]['dflt_value'],
'key' => $this->index['PRI'],
'extra' => 'auto_increment',
'length' => $this->columns['integer']['limit']
);
}
}
$this->__cacheDescription($model->tablePrefix . $model->table, $fields);
@ -246,6 +257,17 @@ class DboSqlite extends DboSource {
}
return false;
}
/**
* Deletes all the records in a table and resets the count of the auto-incrementing
* primary key, where applicable.
*
* @param mixed $table A string or model class representing the table to be truncated
* @return boolean SQL TRUNCATE TABLE statement, false if not applicable.
* @access public
*/
function truncate($table) {
return $this->execute('DELETE From ' . $this->fullTableName($table));
}
/**
* Returns a formatted error message from previous database operation.
*
@ -405,5 +427,60 @@ class DboSqlite extends DboSource {
$this->query("INSERT INTO {$table} ({$fields}) VALUES {$values[$x]}");
}
}
/**
* Generate a database-native column schema string
*
* @param array $column An array structured like the following: array('name'=>'value', 'type'=>'value'[, options]),
* where options can be 'default', 'length', or 'key'.
* @return string
*/
function buildColumn($column) {
$name = $type = null;
$column = am(array('null' => true), $column);
extract($column);
if (empty($name) || empty($type)) {
trigger_error('Column name or type not defined in schema', E_USER_WARNING);
return null;
}
if (!isset($this->columns[$type])) {
trigger_error("Column type {$type} does not exist", E_USER_WARNING);
return null;
}
$real = $this->columns[$type];
if (isset($column['key']) && $column['key'] == 'primary') {
$out = $this->name($name) . ' ' . $this->columns['primary_key']['name'];
} else {
$out = $this->name($name) . ' ' . $real['name'];
if (isset($real['limit']) || isset($real['length']) || isset($column['limit']) || isset($column['length'])) {
if (isset($column['length'])) {
$length = $column['length'];
} elseif (isset($column['limit'])) {
$length = $column['limit'];
} elseif (isset($real['length'])) {
$length = $real['length'];
} else {
$length = $real['limit'];
}
$out .= '(' . $length . ')';
}
if (isset($column['key']) && $column['key'] == 'primary') {
$out .= ' NOT NULL';
} elseif (isset($column['default']) && isset($column['null']) && $column['null'] == false) {
$out .= ' DEFAULT ' . $this->value($column['default'], $type) . ' NOT NULL';
} elseif (isset($column['default'])) {
$out .= ' DEFAULT ' . $this->value($column['default'], $type);
} elseif (isset($column['null']) && $column['null'] == true) {
$out .= ' DEFAULT NULL';
} elseif (isset($column['null']) && $column['null'] == false) {
$out .= ' NOT NULL';
}
}
return $out;
}
}
?>

View file

@ -1306,6 +1306,17 @@ class DboSource extends DataSource {
}
return true;
}
/**
* Deletes all the records in a table and resets the count of the auto-incrementing
* primary key, where applicable.
*
* @param mixed $table A string or model class representing the table to be truncated
* @return boolean SQL TRUNCATE TABLE statement, false if not applicable.
* @access public
*/
function truncate($table) {
return $this->execute('TRUNCATE TABLE ' . $this->fullTableName($table));
}
/**
* Creates a default set of conditions from the model if $conditions is null/empty.
*
@ -1810,6 +1821,25 @@ class DboSource extends DataSource {
return false;
}
}
/**
* Gets the length of a database-native column description, or null if no length
*
* @param string $real Real database-layer column type (i.e. "varchar(255)")
* @return integer An integer representing the length of the column
*/
function length($real) {
$col = r(array(')', 'unsigned'), '', $real);
$limit = null;
if (strpos($col, '(') !== false) {
list($col, $limit) = explode('(', $col);
}
if ($limit != null) {
return intval($limit);
}
return null;
}
/**
* Translates between PHP boolean values and Database (faked) boolean values
*
@ -1862,7 +1892,7 @@ class DboSource extends DataSource {
return false;
}
/**
* Generate a create syntax from CakeSchema
* Generate a database-native schema for the given Schema object
*
* @param object $schema An instance of a subclass of CakeSchema
* @param string $table Optional. If specified only the table name given will be generated.
@ -1870,7 +1900,42 @@ class DboSource extends DataSource {
* @return string
*/
function createSchema($schema, $table = null) {
return false;
if (!is_a($schema, 'CakeSchema')) {
trigger_error(__('Invalid schema object', true), E_USER_WARNING);
return null;
}
$out = '';
foreach ($schema->tables as $curTable => $columns) {
if (!$table || $table == $curTable) {
$out .= 'CREATE TABLE ' . $this->fullTableName($curTable) . " (\n";
$cols = $colList = $index = array();
$primary = null;
foreach ($columns as $name => $col) {
if (is_string($col)) {
$col = array('type' => $col);
}
if (isset($col['key']) && $col['key'] == 'primary') {
$primary = $name;
}
if($name !== 'indexes') {
$col['name'] = $name;
if(!isset($col['type'])) {
$col['type'] = 'string';
}
$cols[] = $this->buildColumn($col);
} else {
$index[] = $this->buildIndex($col);
}
}
if(empty($index) && !empty($primary)) {
$col = array('PRIMARY' => array('column'=> $primary, 'unique' => 1));
$index[] = $this->buildIndex($col);
}
$out .= "\t" . join(",\n\t", array_filter(am($cols, $index))) . "\n);\n\n";
}
}
return $out;
}
/**
* Generate a alter syntax from CakeSchema::compare()
@ -1882,7 +1947,7 @@ class DboSource extends DataSource {
return false;
}
/**
* Generate a drop syntax from CakeSchema
* Generate a "drop table" statement for the given Schema object
*
* @param object $schema An instance of a subclass of CakeSchema
* @param string $table Optional. If specified only the table name given will be generated.
@ -1890,17 +1955,71 @@ class DboSource extends DataSource {
* @return string
*/
function dropSchema($schema, $table = null) {
return false;
if (!is_a($schema, 'CakeSchema')) {
trigger_error(__('Invalid schema object', true), E_USER_WARNING);
return null;
}
$out = '';
foreach ($schema->tables as $curTable => $columns) {
if (!$table || $table == $curTable) {
$out .= 'DROP TABLE ' . $this->fullTableName($curTable) . ";\n";
}
}
return $out;
}
/**
* Generate a column schema string
* Generate a database-native column schema string
*
* @param array $column An array structured like the following: array('name'=>'value', 'type'=>'value'[, options]),
* where options can be 'default', 'length', or 'key'.
* @return string
*/
function buildColumn($column) {
return false;
$name = $type = null;
$column = am(array('null' => true), $column);
extract($column);
if (empty($name) || empty($type)) {
trigger_error('Column name or type not defined in schema', E_USER_WARNING);
return null;
}
if (!isset($this->columns[$type])) {
trigger_error("Column type {$type} does not exist", E_USER_WARNING);
return null;
}
$real = $this->columns[$type];
$out = $this->name($name) . ' ' . $real['name'];
if (isset($real['limit']) || isset($real['length']) || isset($column['limit']) || isset($column['length'])) {
if (isset($column['length'])) {
$length = $column['length'];
} elseif (isset($column['limit'])) {
$length = $column['limit'];
} elseif (isset($real['length'])) {
$length = $real['length'];
} else {
$length = $real['limit'];
}
$out .= '(' . $length . ')';
}
if (isset($column['key']) && $column['key'] == 'primary' && (isset($column['extra']) && $column['extra'] == 'auto_increment')) {
$out .= ' NOT NULL AUTO_INCREMENT';
} elseif (isset($column['key']) && $column['key'] == 'primary') {
$out .= ' NOT NULL';
} elseif (isset($column['default']) && isset($column['null']) && $column['null'] == false) {
$out .= ' DEFAULT ' . $this->value($column['default'], $type) . ' NOT NULL';
} elseif (isset($column['default'])) {
$out .= ' DEFAULT ' . $this->value($column['default'], $type);
} elseif (isset($column['null']) && $column['null'] == true) {
$out .= ' DEFAULT NULL';
} elseif (isset($column['null']) && $column['null'] == false) {
$out .= ' NOT NULL';
}
return $out;
}
/**
* Format indexes for create table

View file

@ -716,7 +716,12 @@ class FormHelper extends AppHelper {
$output = null;
if (isset($object) && isset($options['value']) && ($options['value'] == 0 || $options['value'] == 1)) {
$db =& ConnectionManager::getDataSource($object->useDbConfig);
$value = $db->boolean($options['value'], false);
if (is_object($db)) {
$value = $db->boolean($options['value'], false);
} else {
pr(get_class($object));
pr($object->useDbConfig);
}
$options['value'] = 1;
}
$output = $this->hidden($fieldName, array('value' => '0', 'id' => $options['id'] . '_'), true);

View file

@ -43,7 +43,7 @@ class ContactTestController extends Controller {
var $uses = null;
}
class Contact extends Model {
class Contact extends CakeTestModel {
var $primaryKey = 'id';
var $useTable = false;
var $name = 'Contact';
@ -58,7 +58,7 @@ class Contact extends Model {
}
}
class UserForm extends Model {
class UserForm extends CakeTestModel {
var $useTable = false;
var $primaryKey = 'id';
var $name = 'UserForm';
@ -73,7 +73,7 @@ class UserForm extends Model {
}
}
class OpenidUrl extends Model {
class OpenidUrl extends CakeTestModel {
var $useTable = false;
var $primaryKey = 'id';
var $name = 'OpenidUrl';
@ -92,7 +92,7 @@ class OpenidUrl extends Model {
}
}
class ValidateUser extends Model {
class ValidateUser extends CakeTestModel {
var $primaryKey = 'id';
var $useTable = false;
var $name = 'ValidateUser';
@ -113,7 +113,7 @@ class ValidateUser extends Model {
}
}
class ValidateProfile extends Model {
class ValidateProfile extends CakeTestModel {
var $primaryKey = 'id';
var $useTable = false;
var $name = 'ValidateProfile';
@ -137,7 +137,7 @@ class ValidateProfile extends Model {
}
}
class ValidateItem extends Model {
class ValidateItem extends CakeTestModel {
var $primaryKey = 'id';
var $useTable = false;
var $name = 'ValidateItem';
@ -166,7 +166,10 @@ class ValidateItem extends Model {
*/
class FormHelperTest extends CakeTestCase {
var $fixtures = array(null);
function setUp() {
parent::setUp();
Router::reload();
ClassRegistry::addObject('view', $view);
@ -179,6 +182,7 @@ class FormHelperTest extends CakeTestCase {
}
function startTest($method) {
parent::startTest($method);
$this->Form =& new FormHelper();
$this->Form->Html =& new HtmlHelper();
$this->Controller =& new ContactTestController();
@ -186,6 +190,7 @@ class FormHelperTest extends CakeTestCase {
}
function endTest($method) {
parent::endTest($method);
if (isset($this->Form)) {
unset($this->Form->Html);
unset($this->Form);

View file

@ -156,20 +156,6 @@ class CakeTestFixture extends Object {
}
return $this->_drop;
}
/**
* Run after each tests is executed, should return SQL statement to empty of records the table for this fixture.
*
* @return string SQL TRUNCATE TABLE statement, false if not applicable.
*
* @access public
*/
function truncate() {
if (!isset($this->_truncate)) {
$this->_truncate = 'TRUNCATE TABLE ' . $this->db->name($this->db->config['prefix'] . $this->table);
}
return $this->_truncate;
}
/**
* Run before each tests is executed, should return a set of SQL statements to insert records for the table of this fixture.
*