Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Model rules for default values #420

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 57 additions & 2 deletions src/generators/model/Generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -330,11 +330,68 @@ public function generateLabels($table)
* Generates validation rules for the specified table.
* @param \yii\db\TableSchema $table the table schema
* @return array the generated validation rules
* @throws NotSupportedException
*/
public function generateRules($table)
{
$types = [];
$lengths = [];
$rules = [];
$driverName = $this->getDbDriverName();

if (in_array($driverName, ['mysql', 'sqlite'], true)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why only that's drivers?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know only MySql.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sure just about MySql

Copy link
Contributor

@WinterSilence WinterSilence Apr 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@uldisn that's types normalized check DB subfolders, also:

/**
 * @var string abstract type of this column. Possible abstract types include:
 * char, string, text, boolean, smallint, integer, bigint, float, decimal, datetime,
 * timestamp, time, date, binary, and money.
 */
public $type;
/**
 * @var string the PHP type of this column. Possible PHP types include:
 * `string`, `boolean`, `integer`, `double`, `array`.
 */
public $phpType;

as you can see, $phpType use only 5 types, you can detect numeric as if (in_array($column->phpType, ['integer', 'double', 'float'], true)) 'float' added because php dont have type 'double', i think it's used to set validation rule


$db = $this->getDbConnection();
$columnsDefaultNull = [];
$columnsDefaultValues = [];

foreach ($table->columns as $column) {

if ($column->defaultValue === null) {
if ($column->allowNull) {
$columnsDefaultNull[] = $column->name;
}
continue;
}
switch ($column->type) {
case Schema::TYPE_SMALLINT:
case Schema::TYPE_INTEGER:
case Schema::TYPE_BIGINT:
case Schema::TYPE_TINYINT:
case Schema::TYPE_BOOLEAN:
case Schema::TYPE_FLOAT:
case Schema::TYPE_DOUBLE:
case Schema::TYPE_DECIMAL:
case Schema::TYPE_MONEY:
$defaultValue = $column->defaultValue;
break;

case Schema::TYPE_DATETIME:
case Schema::TYPE_TIMESTAMP:
if(strtoupper($column->defaultValue) === 'CURRENT_TIMESTAMP'){
$defaultValue = 'date(\'Y-m-d H:i:s\')';
}else{
$defaultValue = $db->getSchema()->quoteValue($column->defaultValue);
}
break;

default:
$defaultValue = $db->getSchema()->quoteValue($column->defaultValue);
}
$columnsDefaultValues[$defaultValue][] = $column->name;
}

foreach($columnsDefaultValues as $defaultValue => $columnNameList){
$rules[] = "[['" . implode("', '", $columnNameList) . "'], 'default', 'value' => $defaultValue]";
}

if ($columnsDefaultNull) {
$rules[] = "[['" . implode("', '", $columnsDefaultNull) . "'], 'default', 'value' => null]";
}
}



foreach ($table->columns as $column) {
if ($column->autoIncrement) {
continue;
Expand Down Expand Up @@ -373,8 +430,6 @@ public function generateRules($table)
}
}
}
$rules = [];
$driverName = $this->getDbDriverName();
foreach ($types as $type => $columns) {
if ($driverName === 'pgsql' && $type === 'integer') {
$rules[] = "[['" . implode("', '", $columns) . "'], 'default', 'value' => null]";
Expand Down
2 changes: 1 addition & 1 deletion tests/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@
Yii::setAlias('@yiiunit/gii', __DIR__);
Yii::setAlias('@yii/gii', dirname(__DIR__) . '/src');

require_once(__DIR__ . '/compatibility.php');
require_once(__DIR__ . '/compatibility.php');
2 changes: 1 addition & 1 deletion tests/data/sqlite.sql
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ CREATE TABLE "customer" (
id INTEGER NOT NULL,
email varchar(128) NOT NULL,
name varchar(128),
address text,
address text DEFAULT '-',
status INTEGER DEFAULT 0,
profile_id INTEGER,
PRIMARY KEY (id)
Expand Down
53 changes: 53 additions & 0 deletions tests/generators/ModelGeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -384,4 +384,57 @@ public function testGenerateProperties($tableName, $columns)
}

}

/**
* @return array
*/
public function rulesDefaultValuesProvider()
{
return [
[
'tableName' => 'customer',
'columns' => [
[
'columnName' => 'name',
'rule' => '[[\'status\'], \'default\', \'value\' => 0]',
],
[
'columnName' => 'address',
'rule' => '[[\'name\', \'profile_id\'], \'default\', \'value\' => null]',
],
[
'columnName' => 'address',
'rule' => '[[\'address\'], \'default\', \'value\' => \'-\']',
],
]
],
];

}

/**
* @dataProvider rulesDefaultValuesProvider
*
* @param string $tableName
* @param array $columns
*/
public function testRulesDefaultValues($tableName, $columns)
{
$generator = new ModelGenerator();
$generator->template = 'default';
$generator->tableName = $tableName;

$files = $generator->generate();

$code = $files[0]->content;
foreach ($columns as $column) {
$location = strpos($code, $column['rule']);
$this->assertTrue(
$location !== false,
"Column \"{$column['columnName']}\" rule should be there:\n" . $column['rule']
);
}

}

}