Skip to content
Open
Show file tree
Hide file tree
Changes from 14 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
45 changes: 43 additions & 2 deletions src/generators/model/Generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,49 @@ public function generateRules($table)
{
$types = [];
$lengths = [];
$rules = [];
$driverName = $this->getDbDriverName();

/**
* Default values
*/
$columnsDefaultNull = [];
$columnsDefaultValues = [];
foreach ($table->columns as $column) {
if (in_array($driverName, ['mysql', 'sqlite'], true)) {
/**
* text default values quote
*/
if ($column->defaultValue !== null) {
Copy link
Contributor

Choose a reason for hiding this comment

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

if ($column->defaultValue === null && !$column->allowNull) { continue; }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not need "&& !$column->allowNull"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok

Copy link
Contributor

Choose a reason for hiding this comment

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

@uldisn no need $columnsDefaultNull set if ($column->allowNull) {$defaultValue = 'null';}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

by default all attributes has null value. Not need.

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 null !== 'null', echo null or echo false don't print null or false, in my packages I use <?=json_encode($var)?>

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 checked MySql schema. If in MySql field no default value, then $column->defaultValue is null.
$column->allowNull use for rules "required"
Correct:

 if ($column->defaultValue === null) { continue; }

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 $column->allowNull is @param type|null $foo, function setFoo(?type $value) and function getFoo(): ?type.

If in MySql field no default value, then $column->defaultValue is null.

CREATE TABLE `demo` (`a` VARCHAR(255) NULL, `b` TEXT NULL);
INSERT INTO `demo` (`a`) VALUES (NULL); // (NULL, NULL)
CREATE TABLE ` demo` (
    `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
    `a` TEXT NULL DEFAULT NULL,
    `b` VARCHAR(50) NULL DEFAULT 'is default'
    PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB;

INSERT INTO ` demo` (`a`, `b`) VALUES ('...', NULL);
INSERT INTO ` demo` (`a`, `b`) VALUES (NULL, '...');
INSERT INTO `demo` (`b`) VALUES (NULL);
INSERT INTO `demo` (`a`) VALUES ('...');

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;
default:
$defaultValue = '\'' . $column->defaultValue . '\'';
}
$columnsDefaultValues[$defaultValue][] = $column->name;
} elseif ($column->allowNull) {
$columnsDefaultNull[] = $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 +416,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']
);
}

}

}