Skip to content

Commit 58f48a3

Browse files
authored
Merge pull request #27 from vossik/sql_generator
Sql generator - comment and foreign key attributes
2 parents 6f40270 + ce61872 commit 58f48a3

7 files changed

Lines changed: 121 additions & 31 deletions

File tree

src/Attribute/Comment.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace CoolBeans\Attribute;
6+
7+
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_CLASS)]
8+
final class Comment
9+
{
10+
public function __construct(
11+
public string $comment,
12+
)
13+
{
14+
}
15+
}

src/Attribute/ForeignKey.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace CoolBeans\Attribute;
6+
7+
#[\Attribute(\Attribute::TARGET_PROPERTY)]
8+
final class ForeignKey
9+
{
10+
public function __construct(
11+
public string $table,
12+
public string $column = 'id',
13+
)
14+
{
15+
}
16+
}

src/Attribute/TypeOverride.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,6 @@ public function getType() : string
2323
return $this->type;
2424
}
2525

26-
return $this->type . '(' . \implode(',', $this->lengthArgs) . ')';
26+
return $this->type . '(' . \implode(', ', $this->lengthArgs) . ')';
2727
}
2828
}

src/Command/SqlGeneratorCommand.php

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ private function generateSqlForBean(string $className) : string
7575
'dataType' => $this->getDataType($property),
7676
'notNull' => $this->getNotNull($property),
7777
'default' => $this->getDefault($property),
78+
'comment' => $this->getComment($property),
7879
];
7980

8081
$foreignKey = $this->getForeignKey($property);
@@ -95,7 +96,9 @@ private function generateSqlForBean(string $className) : string
9596
$toReturn .= $this->printSection($foreignKeys);
9697
$toReturn .= \PHP_EOL . ')' . \PHP_EOL;
9798
$toReturn .= self::INDENTATION . 'CHARSET = `utf8mb4`' . \PHP_EOL;
98-
$toReturn .= self::INDENTATION . 'COLLATE = `utf8mb4_general_ci`;';
99+
$toReturn .= self::INDENTATION . 'COLLATE = `utf8mb4_general_ci`';
100+
$toReturn .= $this->getTableComment($bean);
101+
$toReturn .= ';';
99102

100103
return $toReturn;
101104
}
@@ -113,7 +116,8 @@ private function buildTable(array $data) : string
113116
. $row['name'] . \str_repeat(' ', $longestNameLength - $nameLength + 1)
114117
. $row['dataType'] . \str_repeat(' ', $longestDataTypeLength - $dataTypeLength + 1)
115118
. $row['notNull']
116-
. $row['default']);
119+
. $row['default']
120+
. $row['comment']);
117121
}
118122

119123
return \implode(',' . \PHP_EOL, $toReturn);
@@ -134,16 +138,43 @@ private function getLongestByType(array $data, string $type) : int
134138
return $maxLength;
135139
}
136140

141+
private function getComment(\ReflectionProperty $property) : string
142+
{
143+
$commentAttribute = $property->getAttributes(\CoolBeans\Attribute\Comment::class);
144+
145+
if (\count($commentAttribute) === 0) {
146+
return '';
147+
}
148+
149+
return ' COMMENT \'' . $commentAttribute[0]->newInstance()->comment . '\'';
150+
}
151+
152+
private function getTableComment(\ReflectionClass $bean) : string
153+
{
154+
$commentAttribute = $bean->getAttributes(\CoolBeans\Attribute\Comment::class);
155+
156+
if (\count($commentAttribute) === 0) {
157+
return '';
158+
}
159+
160+
return \PHP_EOL . self::INDENTATION . 'COMMENT = \'' . $commentAttribute[0]->newInstance()->comment . '\'';
161+
}
162+
137163
private function getDefault(\ReflectionProperty $property) : string
138164
{
139165
if ($property->getName() === 'id') {
140-
return ' AUTOINCREMENT';
166+
return ' AUTO_INCREMENT';
141167
}
142168

143169
$type = $property->getType();
144170
\assert($type instanceof \ReflectionNamedType);
145171

146172
$defaultValueAttribute = $property->getAttributes(\CoolBeans\Attribute\DefaultValue::class);
173+
$typeOverrideAttribute = $property->getAttributes(\CoolBeans\Attribute\TypeOverride::class);
174+
175+
$propertyType = \count($typeOverrideAttribute) > 0
176+
? \strtolower($typeOverrideAttribute[0]->newInstance()->type)
177+
: $type->getName();
147178

148179
if (!$property->hasDefaultValue() && \count($defaultValueAttribute) === 0) {
149180
return '';
@@ -159,11 +190,11 @@ private function getDefault(\ReflectionProperty $property) : string
159190
return ' DEFAULT NULL';
160191
}
161192

162-
if ($type->getName() === 'bool') {
163-
return ' DEFAULT ' . ($defaultValue === true ? '1' : '0');
164-
}
165-
166-
return ' DEFAULT "' . $defaultValue . '"';
193+
return match ($propertyType) {
194+
'bool' => ' DEFAULT ' . ($defaultValue === true ? '1' : '0'),
195+
'int', 'float' => ' DEFAULT ' . $defaultValue,
196+
default => ' DEFAULT \'' . $defaultValue . '\'',
197+
};
167198
}
168199

169200
private function getNotNull(\ReflectionProperty $property) : string
@@ -186,7 +217,7 @@ private function getDataType(\ReflectionProperty $property) : string
186217
'string' => 'VARCHAR(255)',
187218
\Infinityloop\Utils\Json::class => 'JSON',
188219
'int' => 'INT(11)',
189-
'float' => 'DOUBLE(11)',
220+
'float' => 'DOUBLE',
190221
'bool' => 'TINYINT(1)',
191222
\CoolBeans\PrimaryKey\IntPrimaryKey::class => 'INT(11) UNSIGNED',
192223
\DateTime::class, \Nette\Utils\DateTime::class => 'DATETIME',
@@ -284,9 +315,19 @@ private function getForeignKey(\ReflectionProperty $property) : ?string
284315
return null;
285316
}
286317

287-
$tableName = \str_replace('_id', '', $property->getName());
318+
$foreignKeyAttribute = $property->getAttributes(\CoolBeans\Attribute\ForeignKey::class);
319+
320+
if (\count($foreignKeyAttribute) > 0) {
321+
$foreignKey = $foreignKeyAttribute[0]->newInstance();
322+
323+
$table = $foreignKey->table;
324+
$column = $foreignKey->column;
325+
} else {
326+
$table = \str_replace('_id', '', $property->getName());
327+
$column = 'id';
328+
}
288329

289-
return self::INDENTATION . 'FOREIGN KEY (`' . $property->getName() . '`) REFERENCES `' . $tableName . '`(`id`)';
330+
return self::INDENTATION . 'FOREIGN KEY (`' . $property->getName() . '`) REFERENCES `' . $table . '`(`' . $column . '`)';
290331
}
291332

292333
private function getBeans(string $destination) : array

tests/Unit/Command/SqlGeneratorCommandTest.php

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,15 @@ public function testSimple() : void
1717
{
1818
$expected = <<<'EOL'
1919
CREATE TABLE `attribute_bean`(
20-
`col2` DATE NOT NULL DEFAULT NOW(),
21-
`col3` TIME NOT NULL DEFAULT NOW(),
22-
`col4` BIGINT NOT NULL,
23-
`col5` INT(44) NOT NULL DEFAULT "1",
24-
`col6` DECIMAL(1,3) NOT NULL DEFAULT "1",
25-
`col7_id` INT(11) UNSIGNED NOT NULL,
20+
`col2` DATE NOT NULL DEFAULT NOW(),
21+
`col3` TIME NOT NULL DEFAULT NOW(),
22+
`col4` BIGINT NOT NULL,
23+
`col5` INT(44) NOT NULL DEFAULT 1 COMMENT 'Some random comment',
24+
`col6` DECIMAL(1, 3) NOT NULL DEFAULT '1.005',
25+
`col7_id` INT(11) UNSIGNED NOT NULL,
26+
`col8` DOUBLE(16, 2) NOT NULL,
27+
`col9_id` INT(11) UNSIGNED NOT NULL,
28+
`col10_id` INT(11) UNSIGNED NOT NULL,
2629
2730
CONSTRAINT `unique_attribute_bean_col2_col3` UNIQUE (`col2`,`col3`),
2831
CONSTRAINT `unique_attribute_bean_col4_col5_col6` UNIQUE (`col4`,`col5`,`col6`),
@@ -31,44 +34,49 @@ public function testSimple() : void
3134
CONSTRAINT `unique_attribute_bean_col5` UNIQUE (`col5`),
3235
CONSTRAINT `unique_attribute_bean_col6` UNIQUE (`col6`),
3336
34-
FOREIGN KEY (`col7_id`) REFERENCES `col7`(`id`)
37+
FOREIGN KEY (`col7_id`) REFERENCES `col7`(`id`),
38+
FOREIGN KEY (`col9_id`) REFERENCES `test_table`(`test_column`),
39+
FOREIGN KEY (`col10_id`) REFERENCES `test_table`(`id`)
3540
)
3641
CHARSET = `utf8mb4`
37-
COLLATE = `utf8mb4_general_ci`;
42+
COLLATE = `utf8mb4_general_ci`
43+
COMMENT = 'Some random comment';
3844
3945
CREATE TABLE `simple_bean_1`(
40-
`id` INT(11) UNSIGNED NOT NULL AUTOINCREMENT,
46+
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
4147
`col3` VARCHAR(255) NOT NULL,
4248
`col4` VARCHAR(255),
4349
`col5` VARCHAR(255) DEFAULT NULL,
44-
`col6` VARCHAR(255) DEFAULT "default",
50+
`col6` VARCHAR(255) DEFAULT 'default',
4551
`col7_id` INT(11) UNSIGNED NOT NULL,
4652
`col8` DATETIME NOT NULL,
4753
`col9` DATETIME NOT NULL,
54+
`col10` INT(11) NOT NULL DEFAULT 5,
55+
`col11` DOUBLE NOT NULL DEFAULT 0.005,
4856
4957
FOREIGN KEY (`col7_id`) REFERENCES `col7`(`id`)
5058
)
5159
CHARSET = `utf8mb4`
5260
COLLATE = `utf8mb4_general_ci`;
5361
5462
CREATE TABLE `simple_bean_2`(
55-
`id` INT(11) UNSIGNED NOT NULL AUTOINCREMENT,
63+
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
5664
`col3` VARCHAR(255) NOT NULL,
5765
`col4` VARCHAR(255),
5866
`col5` VARCHAR(255) DEFAULT NULL,
59-
`col6` VARCHAR(255) DEFAULT "default",
67+
`col6` VARCHAR(255) DEFAULT 'default',
6068
`col8` DATETIME NOT NULL,
6169
`col9` DATETIME NOT NULL
6270
)
6371
CHARSET = `utf8mb4`
6472
COLLATE = `utf8mb4_general_ci`;
6573
6674
CREATE TABLE `simple_bean_attribute`(
67-
`id` INT(11) UNSIGNED NOT NULL AUTOINCREMENT,
75+
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
6876
`col3` VARCHAR(255) NOT NULL,
6977
`col4` VARCHAR(255),
7078
`col5` VARCHAR(255) DEFAULT NULL,
71-
`col6` VARCHAR(255) DEFAULT "default",
79+
`col6` VARCHAR(255) DEFAULT 'default',
7280
`col8` DATETIME NOT NULL,
7381
`col9` DATETIME NOT NULL,
7482
@@ -78,11 +86,11 @@ public function testSimple() : void
7886
COLLATE = `utf8mb4_general_ci`;
7987
8088
CREATE TABLE `simple_bean_class_attribute`(
81-
`id` INT(11) UNSIGNED NOT NULL AUTOINCREMENT,
89+
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
8290
`col3` VARCHAR(255) NOT NULL,
8391
`col4` VARCHAR(255),
8492
`col5` VARCHAR(255) DEFAULT NULL,
85-
`col6` VARCHAR(255) DEFAULT "default",
93+
`col6` VARCHAR(255) DEFAULT 'default',
8694
`col8` DATETIME NOT NULL,
8795
`col9` DATETIME NOT NULL,
8896
@@ -92,11 +100,11 @@ public function testSimple() : void
92100
COLLATE = `utf8mb4_general_ci`;
93101
94102
CREATE TABLE `simple_bean_class_attribute_2`(
95-
`id` INT(11) UNSIGNED NOT NULL AUTOINCREMENT,
103+
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
96104
`col3` VARCHAR(255) NOT NULL,
97105
`col4` VARCHAR(255),
98106
`col5` VARCHAR(255) DEFAULT NULL,
99-
`col6` VARCHAR(255) DEFAULT "default",
107+
`col6` VARCHAR(255) DEFAULT 'default',
100108
`col8` DATETIME NOT NULL,
101109
`col9` DATETIME NOT NULL,
102110

tests/Unit/TestBean/AttributeBean.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
//@phpcs:disable Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
1010
#[\CoolBeans\Attribute\ClassUniqueConstraint(['col2', 'col3'])]
1111
#[\CoolBeans\Attribute\ClassUniqueConstraint(['col4', 'col5', 'col6'])]
12+
#[\CoolBeans\Attribute\Comment('Some random comment')]
1213
final class AttributeBean extends \CoolBeans\Bean
1314
{
1415
#[\CoolBeans\Attribute\DefaultValue(\CoolBeans\Attribute\Defaults\MysqlDefaults::NOW)]
@@ -25,9 +26,16 @@ final class AttributeBean extends \CoolBeans\Bean
2526
public int $col4;
2627
#[\CoolBeans\Attribute\TypeOverride(\CoolBeans\Attribute\Types\MysqlTypes::INT, 44)]
2728
#[\CoolBeans\Attribute\UniqueConstraint]
29+
#[\CoolBeans\Attribute\Comment('Some random comment')]
2830
public float $col5 = 1;
2931
#[\CoolBeans\Attribute\TypeOverride(\CoolBeans\Attribute\Types\MysqlTypes::DECIMAL, 1, 3)]
3032
#[\CoolBeans\Attribute\UniqueConstraint]
31-
public float $col6 = 1;
33+
public float $col6 = 1.005;
3234
public \CoolBeans\PrimaryKey\IntPrimaryKey $col7_id;
35+
#[\CoolBeans\Attribute\TypeOverride(\CoolBeans\Attribute\Types\MysqlTypes::DOUBLE, 16, 2)]
36+
public float $col8;
37+
#[\CoolBeans\Attribute\ForeignKey('test_table', 'test_column')]
38+
public \CoolBeans\PrimaryKey\IntPrimaryKey $col9_id;
39+
#[\CoolBeans\Attribute\ForeignKey('test_table')]
40+
public \CoolBeans\PrimaryKey\IntPrimaryKey $col10_id;
3341
}

tests/Unit/TestBean/SimpleBean1.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,6 @@ final class SimpleBean1 extends \CoolBeans\Bean
1919
public \CoolBeans\PrimaryKey\IntPrimaryKey $col7_id;
2020
public \DateTime $col8;
2121
public \Nette\Utils\DateTime $col9;
22+
public int $col10 = 5;
23+
public float $col11 = 0.005;
2224
}

0 commit comments

Comments
 (0)