Skip to content
Merged
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
15 changes: 15 additions & 0 deletions src/Exceptions/UnknownFieldTypeException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace RonasIT\Support\Exceptions;

use Exception;

class UnknownFieldTypeException extends Exception
{
public function __construct(
protected string $typeName,
protected string $generatorName,
) {
parent::__construct("Unknown field type {$this->typeName} in {$this->generatorName}.");
}
}
28 changes: 15 additions & 13 deletions src/Generators/MigrationGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
namespace RonasIT\Support\Generators;

use Carbon\Carbon;
use Exception;
use Illuminate\Support\Str;
use RonasIT\Support\Events\SuccessCreateMessage;
use RonasIT\Support\Exceptions\UnknownFieldTypeException;

class MigrationGenerator extends EntityGenerator
{
Expand All @@ -24,29 +25,30 @@ public function generate(): void
'fields' => $this->fields,
'table' => $this->generateTable($this->fields)
]);

$now = Carbon::now()->format('Y_m_d_His');

$this->saveClass('migrations', "{$now}_{$entities}_create_table", $content);

event(new SuccessCreateMessage("Created a new Migration: {$entities}_create_table"));
}

protected function isJson($typeName): bool
protected function isJson(string $typeName): bool
{
return $typeName == 'json';
return $typeName === 'json';
}

protected function isRequired($typeName): bool
protected function isRequired(string $typeName): bool
{
return !empty(explode('-', $typeName)[1]);
return Str::afterLast($typeName, '-') === 'required';
}

protected function isNullable($typeName): bool
protected function isNullable(string $typeName): bool
{
return empty(explode('-', $typeName)[1]);
}

protected function getJsonLine($fieldName): string
protected function getJsonLine(string $fieldName): string
{
if (env("DB_CONNECTION") == "mysql") {
return "\$table->json('{$fieldName}')->nullable();";
Expand All @@ -55,7 +57,7 @@ protected function getJsonLine($fieldName): string
return "\$table->jsonb('{$fieldName}')->default(\"{}\");";
}

protected function getRequiredLine($fieldName, $typeName): string
protected function getRequiredLine(string $fieldName, string $typeName): string
{
$type = explode('-', $typeName)[0];

Expand All @@ -66,27 +68,27 @@ protected function getRequiredLine($fieldName, $typeName): string
return "\$table->{$type}('{$fieldName}');";
}

protected function getNonRequiredLine($fieldName, $typeName): string
protected function getNonRequiredLine(string $fieldName, string $typeName): string
{
$type = explode('-', $typeName)[0];

return "\$table->{$type}('{$fieldName}')->nullable();";
}

protected function generateTable($fields): array
protected function generateTable(array $fields): array
{
$resultTable = [];

foreach ($fields as $typeName => $fieldNames) {
foreach ($fieldNames as $fieldName) {
array_push($resultTable, $this->getTableRow($fieldName, $typeName));
$resultTable[] = $this->getTableRow($fieldName, $typeName);
}
}

return $resultTable;
}

protected function getTableRow($fieldName, $typeName): string
protected function getTableRow(string $fieldName, string $typeName): string
{
if ($this->isJson($typeName)) {
return $this->getJsonLine($fieldName);
Expand All @@ -100,6 +102,6 @@ protected function getTableRow($fieldName, $typeName): string
return $this->getNonRequiredLine($fieldName, $typeName);
}

throw new Exception('Unknown fieldType in MigrationGenerator');
throw new UnknownFieldTypeException($typeName, 'MigrationGenerator');
}
}
2 changes: 1 addition & 1 deletion stubs/migration.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,4 @@ public function createTable(): void
});
}
@endif
};
};
91 changes: 91 additions & 0 deletions tests/MigrationGeneratorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php

namespace RonasIT\Support\Tests;

use Illuminate\Support\Carbon;
use RonasIT\Support\Exceptions\UnknownFieldTypeException;
use RonasIT\Support\Generators\MigrationGenerator;
use RonasIT\Support\Tests\Support\Migration\MigrationMockTrait;

class MigrationGeneratorTest extends TestCase
{
use MigrationMockTrait;

public function testSetUnknownFieldType()
{
$this->setupConfigurations();

$this->assertExceptionThrew(
className: UnknownFieldTypeException::class,
message: 'Unknown field type unknown-type in MigrationGenerator.',
);

app(MigrationGenerator::class)
->setModel('Post')
->setRelations([
'belongsTo' => [],
'belongsToMany' => [],
'hasOne' => [],
'hasMany' => [],
])
->setFields([
'integer-required' => ['media_id', 'user_id'],
'unknown-type' => ['title'],
])
->generate();
}

public function testCreateMigration()
{
Carbon::setTestNow('2022-02-02');

$this->mockFilesystem();
$this->setupConfigurations();

app(MigrationGenerator::class)
->setModel('Post')
->setRelations([
'belongsTo' => [],
'belongsToMany' => [],
'hasOne' => [],
'hasMany' => [],
])
->setFields([
'integer-required' => ['media_id', 'user_id'],
'string' => ['title', 'body'],
'json' => ['meta'],
'timestamp' => ['created_at'],
])
->generate();

$this->assertGeneratedFileEquals('migrations.php', 'database/migrations/2022_02_02_000000_posts_create_table.php');
}

public function testCreateMigrationMYSQL()
{
putenv('DB_CONNECTION=mysql');

Carbon::setTestNow('2022-02-02');

$this->mockFilesystem();
$this->setupConfigurations();

app(MigrationGenerator::class)
->setModel('Post')
->setRelations([
'belongsTo' => [],
'belongsToMany' => [],
'hasOne' => [],
'hasMany' => [],
])
->setFields([
'integer-required' => ['media_id', 'user_id'],
'string' => ['title', 'body'],
'json' => ['meta'],
'timestamp' => ['created_at'],
])
->generate();

$this->assertGeneratedFileEquals('migrations_mysql.php', 'database/migrations/2022_02_02_000000_posts_create_table.php');
}
}
32 changes: 32 additions & 0 deletions tests/Support/Migration/MigrationMockTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace RonasIT\Support\Tests\Support\Migration;

use org\bovigo\vfs\vfsStream;
use RonasIT\Support\Tests\Support\GeneratorMockTrait;

trait MigrationMockTrait
{
use GeneratorMockTrait;

public function setupConfigurations(): void
{
config([
'entity-generator.stubs.migration' => 'entity-generator::migration',
'entity-generator.paths' => [
'migrations' => 'database/migrations',
]
]);
}

public function mockFilesystem(): void
{
$structure = [
'database' => [
'migrations' => [],
],
];

vfsStream::create($structure);
}
}
30 changes: 30 additions & 0 deletions tests/fixtures/MigrationGeneratorTest/migrations.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use RonasIT\Support\Traits\MigrationTrait;

return new class extends Migration
{
use MigrationTrait;

public function up(): void
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->integer('media_id');
$table->integer('user_id');
$table->string('title')->nullable();
$table->string('body')->nullable();
$table->jsonb('meta')->default("{}");
$table->timestamp('created_at')->nullable();
$table->timestamps();
});
}

public function down(): void
{
Schema::dropIfExists('posts');
}
};
30 changes: 30 additions & 0 deletions tests/fixtures/MigrationGeneratorTest/migrations_mysql.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use RonasIT\Support\Traits\MigrationTrait;

return new class extends Migration
{
use MigrationTrait;

public function up(): void
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->integer('media_id');
$table->integer('user_id');
$table->string('title')->nullable();
$table->string('body')->nullable();
$table->json('meta')->nullable();
$table->timestamp('created_at')->nullable();
$table->timestamps();
});
}

public function down(): void
{
Schema::dropIfExists('posts');
}
};
Loading