Skip to content

Commit 25da464

Browse files
authored
Merge pull request #4 from SOHELAHMED7/master
Resolve: Create migration for drop table if a entire schema is deleted from OpenAPI spec
2 parents a16ac6c + e4bcd76 commit 25da464

File tree

101 files changed

+2028
-132
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+2028
-132
lines changed

README.md

+18-1
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,23 @@ Provide custom database table column name in case of relationship column. This w
319319
- x-fk-column-name: redelivery_of # this will create `redelivery_of` column instead of `redelivery_of_id`
320320
```
321321
322+
323+
### `x-deleted-schemas`
324+
325+
This is root level key used to generate "drop table" migration for the deleted component schema. If a component schema (DB model) is removed from OpenAPI spec then its following entities should be also deleted from the code:
326+
327+
- DB table (migrations)
328+
- model
329+
- faker
330+
331+
So to generate appropriate migration for the removed schema, explicitly setting schema name or schema name + custom table name is required in this key. Only then the migrations will be generated. It should be set as:
332+
333+
```yaml
334+
x-deleted-schemas:
335+
- Fruit # Example: table name is evaluated to `itt_fruits`, if `itt_` is prefix set in DB config
336+
- Mango: the_mango_table_name # custom table name; see `x-table` in README.md
337+
```
338+
322339
### `x-no-relation`
323340

324341
To differentiate a component schema property from one-to-many or many-to-many relation in favour of array(json) of
@@ -443,7 +460,7 @@ paths:
443460
Generated URL rules config for above is (in `urls.rest.php` or pertinent file):
444461
```php
445462
'GET a1/b1' => 'abc/xyz',
446-
'POST a1/b1' => 'abc/xyz',
463+
'POST a1/b1' => 'abc/xyz',
447464
'a1/b1' => 'abc/options',
448465
```
449466
`x-route` does not support [Yii Modules](https://www.yiiframework.com/doc/guide/2.0/en/structure-modules).

composer.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@
2323
"yiisoft/yii2": "~2.0.48",
2424
"yiisoft/yii2-gii": "~2.0.0 | ~2.1.0 | ~2.2.0| ~2.3.0",
2525
"laminas/laminas-code": ">=3.4 <=4.13",
26-
"php-openapi/yii2-fractal": "^1.0.0",
26+
"php-openapi/yii2-fractal": "^1.4",
2727
"fakerphp/faker": "^1.9",
2828
"sam-it/yii2-mariadb": "^2.0",
2929
"symfony/var-exporter": "^5.4",
30-
"symfony/polyfill-php80": "^1.30"
30+
"symfony/polyfill-php80": "^1.31"
3131
},
3232
"require-dev": {
3333
"cebe/indent": "*",

src/generator/ApiGenerator.php

+22-17
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77

88
namespace cebe\yii2openapi\generator;
99

10+
use cebe\openapi\exceptions\IOException;
11+
use cebe\openapi\exceptions\TypeErrorException;
12+
use cebe\openapi\exceptions\UnresolvableReferenceException;
1013
use cebe\yii2openapi\lib\items\DbModel;
1114
use cebe\openapi\Reader;
1215
use cebe\openapi\spec\OpenApi;
@@ -22,6 +25,7 @@
2225
use cebe\yii2openapi\lib\items\RestAction;
2326
use cebe\yii2openapi\lib\PathAutoCompletion;
2427
use cebe\yii2openapi\lib\SchemaToDatabase;
28+
use Exception;
2529
use Yii;
2630
use yii\db\mysql\Schema as MySqlSchema;
2731
use SamIT\Yii2\MariaDb\Schema as MariaDbSchema;
@@ -190,7 +194,7 @@ class ApiGenerator extends Generator
190194
private $_openApiWithoutRef;
191195

192196
/**
193-
* @var \cebe\yii2openapi\lib\Config $config
197+
* @var Config $config
194198
**/
195199
private $config;
196200

@@ -297,11 +301,11 @@ public function rules()
297301

298302
/**
299303
* @param $attribute
300-
* @throws \cebe\openapi\exceptions\IOException
301-
* @throws \cebe\openapi\exceptions\TypeErrorException
302-
* @throws \cebe\openapi\exceptions\UnresolvableReferenceException
304+
* @throws IOException
305+
* @throws TypeErrorException
306+
* @throws UnresolvableReferenceException
303307
*/
304-
public function validateSpec($attribute):void
308+
public function validateSpec($attribute): void
305309
{
306310
if ($this->ignoreSpecErrors) {
307311
return;
@@ -313,7 +317,7 @@ public function validateSpec($attribute):void
313317
}
314318
}
315319

316-
public function validateUrlPrefixes($attribute):void
320+
public function validateUrlPrefixes($attribute): void
317321
{
318322
if (empty($this->urlPrefixes)) {
319323
return;
@@ -441,7 +445,7 @@ public function stickyAttributes()
441445
);
442446
}
443447

444-
public function makeConfig():Config
448+
public function makeConfig(): Config
445449
{
446450
if (!$this->config) {
447451
$props = get_object_vars($this);
@@ -471,11 +475,12 @@ public function makeConfig():Config
471475
* Please refer to [[\yii\gii\generators\controller\Generator::generate()]] as an example
472476
* on how to implement this method.
473477
* @return CodeFile[] a list of code files to be created.
474-
* @throws \Exception
478+
* @throws Exception
475479
*/
476-
public function generate():array
480+
public function generate(): array
477481
{
478482
$config = $this->makeConfig();
483+
479484
$actionsGenerator = $this->useJsonApi
480485
? Yii::createObject(JsonActionGenerator::class, [$config])
481486
: Yii::createObject(RestActionGenerator::class, [$config]);
@@ -504,12 +509,12 @@ public function generate():array
504509
}
505510

506511
/**
507-
* @return \cebe\openapi\spec\OpenApi
508-
* @throws \cebe\openapi\exceptions\IOException
509-
* @throws \cebe\openapi\exceptions\TypeErrorException
510-
* @throws \cebe\openapi\exceptions\UnresolvableReferenceException
512+
* @return OpenApi
513+
* @throws IOException
514+
* @throws TypeErrorException
515+
* @throws UnresolvableReferenceException
511516
*/
512-
protected function getOpenApiWithoutReferences():OpenApi
517+
protected function getOpenApiWithoutReferences(): OpenApi
513518
{
514519
if ($this->_openApiWithoutRef === null) {
515520
$file = Yii::getAlias($this->openApiPath);
@@ -522,17 +527,17 @@ protected function getOpenApiWithoutReferences():OpenApi
522527
return $this->_openApiWithoutRef;
523528
}
524529

525-
public static function isPostgres():bool
530+
public static function isPostgres(): bool
526531
{
527532
return Yii::$app->db->schema instanceof PgSqlSchema;
528533
}
529534

530-
public static function isMysql():bool
535+
public static function isMysql(): bool
531536
{
532537
return (Yii::$app->db->schema instanceof MySqlSchema && !static::isMariaDb());
533538
}
534539

535-
public static function isMariaDb():bool
540+
public static function isMariaDb(): bool
536541
{
537542
return strpos(Yii::$app->db->schema->getServerVersion(), 'MariaDB') !== false;
538543
}

src/lib/AttributeResolver.php

+8-6
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ protected function resolveJunctionTableProperty(PropertySchema $property, bool $
139139
->asReference($junkAttribute['relatedClassName'])
140140
->setPhpType($junkAttribute['phpType'])
141141
->setDbType($junkAttribute['dbType'])
142-
->setForeignKeyColumnName($property->fkColName);
142+
->setForeignKeyColumnName($property->fkColName)
143+
->setTableName($this->componentSchema->resolveTableName($this->schemaName));
143144
$relation = Yii::createObject(AttributeRelation::class, [
144145
$property->getName(),
145146
$junkAttribute['relatedTableName'],
@@ -205,7 +206,7 @@ protected function resolveHasMany2ManyTableProperty(PropertySchema $property, bo
205206
*/
206207
protected function resolveProperty(
207208
PropertySchema $property,
208-
bool $isRequired,
209+
bool $isRequired,
209210
$nullableValue = 'ARG_ABSENT'
210211
): void {
211212
if ($nullableValue === 'ARG_ABSENT') {
@@ -227,7 +228,8 @@ protected function resolveProperty(
227228
->setNullable($nullableValue)
228229
->setIsPrimary($property->isPrimaryKey())
229230
->setForeignKeyColumnName($property->fkColName)
230-
->setFakerStub($this->guessFakerStub($attribute, $property));
231+
->setFakerStub($this->guessFakerStub($attribute, $property))
232+
->setTableName($this->componentSchema->resolveTableName($this->schemaName));
231233
if ($property->isReference()) {
232234
if ($property->isVirtual()) {
233235
throw new InvalidDefinitionException('References not supported for virtual attributes');
@@ -374,9 +376,9 @@ protected function resolveProperty(
374376
* @throws InvalidConfigException|InvalidDefinitionException
375377
*/
376378
protected function catchManyToMany(
377-
string $propertyName,
378-
string $relatedSchemaName,
379-
string $relatedTableName,
379+
string $propertyName,
380+
string $relatedSchemaName,
381+
string $relatedTableName,
380382
ComponentSchema $refSchema
381383
): bool {
382384
if (strtolower(Inflector::id2camel($propertyName, '_'))

src/lib/ColumnToCode.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -399,8 +399,9 @@ private function getIsBuiltinType($type, $dbType)
399399
private function resolveEnumType():void
400400
{
401401
if (ApiGenerator::isPostgres()) {
402-
$rawTableName = $this->dbSchema->getRawTableName($this->tableAlias);
403-
$this->rawParts['type'] = '"enum_'.$rawTableName.'_' . $this->column->name.'"';
402+
// $rawTableName = $this->dbSchema->getRawTableName($this->tableAlias);
403+
// $this->rawParts['type'] = '"enum_'.$rawTableName.'_' . $this->column->name.'"';
404+
$this->rawParts['type'] = '"'.$this->column->dbType.'"';
404405
return;
405406
}
406407
$this->rawParts['type'] = 'enum(' . self::mysqlEnumToString($this->column->enumValues) . ')';

src/lib/CustomSpecAttr.php

+6
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ class CustomSpecAttr
4141
*/
4242
public const FK_COLUMN_NAME = 'x-fk-column-name';
4343

44+
/**
45+
* Drop table Migrations to be generated from removed component schemas
46+
* See README for docs
47+
*/
48+
public const DELETED_SCHEMAS = 'x-deleted-schemas';
49+
4450
/**
4551
* Foreign key column name. See README for usage docs
4652
*/

0 commit comments

Comments
 (0)