Skip to content

Commit e6ecd15

Browse files
committed
added new settings for disabling implications, cleaned the attributes from package imports, updated documentation
1 parent ed85069 commit e6ecd15

34 files changed

+286
-143
lines changed

.wiki

Submodule .wiki updated from a74e950 to b7b8416

Readme.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
- [Configuration](#configuration)
2020
- [`database.model_paths`](#databasemodel_paths)
2121
- [`database.auto_infer_migrations`](#databaseauto_infer_migrations)
22+
- [`database.implications.<implication_name_in_snake>`](#databaseimplicationsimplication_name_in_snake)
2223
- [Manual Migrations](#manual-migrations)
2324
- [Implication Reference](#implication-reference)
2425
- [`Table`](#table)
@@ -249,8 +250,6 @@ Alternatively, you can always install the package with `composer install toraman
249250

250251
# Configuration
251252

252-
There's very little configuration required for using this tool.
253-
254253
## `database.model_paths`
255254

256255
An `array` of paths relative to the project directory where application models reside. The default is a single path the same as Laravel' default model path: `['app/Models']`
@@ -259,6 +258,10 @@ An `array` of paths relative to the project directory where application models r
259258

260259
This is a `boolean` value that controls, you guessed it, whether or not to infer the migration information automatically. What this means is basically, unless specified otherwise with an implication, none of the models, properties or methods are going to be inspected for migration information. If a property or method of a model has an implication, that model will also be inspected. The default is `true`.
261260

261+
## `database.implications.<implication_name_in_snake>`
262+
263+
These are `boolean` values that can be used to enable or disable implications. The implication names have to be in snake case as per Laravel's convention of configuration keys e.g. `database.implications.foreign_key`. This set to `true` by default for all the implications.
264+
262265

263266
# Manual Migrations
264267

src/Attributes/Applicable.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace Toramanlis\ImplicitMigrations\Attributes;
4+
5+
use Illuminate\Database\Schema\Blueprint;
6+
7+
trait Applicable
8+
{
9+
abstract public static function enabled(): bool;
10+
11+
abstract protected function process(Blueprint $table): Blueprint;
12+
13+
public function apply(Blueprint $table): Blueprint
14+
{
15+
if (!$this->enabled()) {
16+
return $table;
17+
}
18+
19+
return $this->process($table);
20+
}
21+
}

src/Attributes/Column.php

Lines changed: 63 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@
33
namespace Toramanlis\ImplicitMigrations\Attributes;
44

55
use Attribute;
6-
use Exception;
6+
use Exception as BaseException;
77
use Illuminate\Database\Schema\Blueprint;
88
use ReflectionProperty;
99
use Illuminate\Support\Str;
1010
use ReflectionNamedType;
1111
use ReflectionType;
12-
use Toramanlis\ImplicitMigrations\Blueprint\Exporters\ColumnExporter;
13-
use Toramanlis\ImplicitMigrations\Exceptions\ImplicationException;
1412

1513
#[Attribute(Attribute::TARGET_PROPERTY | Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]
1614
class Column extends MigrationAttribute
1715
{
16+
use Applicable;
17+
1818
public const TYPE_MAP = [
1919
'array' => 'json',
2020
'bool' => 'boolean',
@@ -49,6 +49,48 @@ class Column extends MigrationAttribute
4949
'computed' => ['expression'],
5050
];
5151

52+
public const SUPPORTED_MODIFIERS = [
53+
'after',
54+
'autoIncrement',
55+
'charset',
56+
'collation',
57+
'comment',
58+
'default',
59+
'first',
60+
'from',
61+
'invisible',
62+
'nullable',
63+
'storedAs',
64+
'unsigned',
65+
'useCurrent',
66+
'useCurrentOnUpdate',
67+
'virtualAs',
68+
'generatedAs',
69+
'always',
70+
];
71+
72+
public const SUPPORTED_ATTRIBUTES = [
73+
'after',
74+
'autoIncrement',
75+
'comment',
76+
'default',
77+
'nullable',
78+
'storedAs',
79+
'unsigned',
80+
'virtualAs',
81+
'length',
82+
'precision',
83+
'total',
84+
'places',
85+
'allowed',
86+
'fixed',
87+
'subtype',
88+
'srid',
89+
'expression',
90+
'collation',
91+
];
92+
93+
5294
protected bool $inferred = false;
5395

5496
public function __construct(
@@ -115,53 +157,42 @@ public function inferFromReflectionProperty(ReflectionProperty $reflection): voi
115157
protected function validate(Blueprint $table)
116158
{
117159
if (empty($this->name)) {
118-
throw new ImplicationException(ImplicationException::CODE_COL_NO_NAME, [$table->getTable()]);
160+
throw new Exception(Exception::CODE_COL_NO_NAME, [$table->getTable()]);
119161
}
120162

121163
if (null === $this->type) {
122-
throw new ImplicationException(ImplicationException::CODE_COL_NO_TYPE, [$table->getTable(), $this->name]);
164+
throw new Exception(Exception::CODE_COL_NO_TYPE, [$table->getTable(), $this->name]);
123165
}
124166
}
125167

126-
public function applyToBlueprint(Blueprint $table): Blueprint
168+
protected function process(Blueprint $table): Blueprint
127169
{
128170
try {
129171
$this->validate($table);
130-
} catch (ImplicationException $e) {
172+
} catch (Exception $e) {
131173
if ($this->inferred) {
132174
return $table;
133175
}
134176

135177
throw $e;
136-
} catch (Exception $e) {
178+
} catch (BaseException $e) {
137179
$reportedName = $this->name ?? '???';
138-
throw new ImplicationException(
139-
ImplicationException::CODE_COL_GENERIC,
180+
throw new Exception(
181+
Exception::CODE_COL_GENERIC,
140182
[$table->getTable(), $reportedName],
141183
$e
142184
);
143185
}
144186

145-
$attributes = array_filter([
146-
'after' => $this->after,
147-
'autoIncrement' => $this->autoIncrement,
148-
'comment' => $this->comment,
149-
'default' => $this->default,
150-
'nullable' => $this->nullable,
151-
'storedAs' => $this->storedAs,
152-
'unsigned' => $this->unsigned,
153-
'virtualAs' => $this->virtualAs,
154-
'length' => $this->length,
155-
'precision' => $this->precision,
156-
'total' => $this->total,
157-
'places' => $this->places,
158-
'allowed' => $this->allowed,
159-
'fixed' => $this->fixed,
160-
'subtype' => $this->subtype,
161-
'srid' => $this->srid,
162-
'expression' => $this->expression,
163-
'collation' => $this->collation,
164-
], fn ($i) => null !== $i);
187+
$attributes = [];
188+
189+
foreach (static::SUPPORTED_ATTRIBUTES as $attributeName) {
190+
if (null === $this->{$attributeName}) {
191+
continue;
192+
}
193+
194+
$attributes[$attributeName] = $this->{$attributeName};
195+
}
165196

166197
$parameters = [];
167198
foreach (static::PARAMETER_MAP[$this->type] ?? [] as $parameterName) {
@@ -175,7 +206,7 @@ public function applyToBlueprint(Blueprint $table): Blueprint
175206
if (
176207
!empty(array_diff(
177208
array_keys($attributes),
178-
ColumnExporter::SUPPORTED_MODIFIERS,
209+
static::SUPPORTED_MODIFIERS,
179210
array_keys($parameters)
180211
))
181212
) {
@@ -185,7 +216,7 @@ public function applyToBlueprint(Blueprint $table): Blueprint
185216

186217
$column = $table->{$this->type}($this->name, ...$parameters);
187218

188-
foreach (ColumnExporter::SUPPORTED_MODIFIERS as $modifier) {
219+
foreach (static::SUPPORTED_MODIFIERS as $modifier) {
189220
if (!isset($attributes[$modifier])) {
190221
continue;
191222
}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<?php
22

3-
namespace Toramanlis\ImplicitMigrations\Exceptions;
3+
namespace Toramanlis\ImplicitMigrations\Attributes;
44

5-
use Exception;
5+
use Exception as BaseException;
66
use Throwable;
77

8-
class ImplicationException extends Exception
8+
class Exception extends BaseException
99
{
1010
final public const CODE_NONE = 0;
1111

src/Attributes/ForeignKey.php

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,18 @@
33
namespace Toramanlis\ImplicitMigrations\Attributes;
44

55
use Attribute;
6-
use Exception;
6+
use Exception as BaseException;
77
use Illuminate\Database\Eloquent\Model;
88
use Illuminate\Database\Schema\Blueprint;
99
use ReflectionProperty;
1010
use Illuminate\Support\Str;
1111
use ReflectionClass;
12-
use Toramanlis\ImplicitMigrations\Exceptions\ImplicationException;
1312

1413
#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)]
1514
class ForeignKey extends MigrationAttribute
1615
{
16+
use Applicable;
17+
1718
protected string|Model $on;
1819
protected ?array $columns;
1920

@@ -96,7 +97,7 @@ protected function getReferencedModelName(array $modelNames): string
9697
}
9798
}
9899

99-
throw new ImplicationException(ImplicationException::CODE_FK_NO_MODEL, [$this->columns[0]]);
100+
throw new Exception(Exception::CODE_FK_NO_MODEL, [$this->columns[0]]);
100101
}
101102

102103
protected function ensureColumn($columnName, Blueprint $table, array $blueprints, array $modelNames): void
@@ -112,7 +113,7 @@ protected function ensureColumn($columnName, Blueprint $table, array $blueprints
112113
$referencedTableName = $this->getReferenceTableName();
113114

114115
if (!isset($blueprints[$referencedTableName])) {
115-
throw new ImplicationException();
116+
throw new Exception();
116117
}
117118

118119
/** @var Blueprint */
@@ -136,8 +137,8 @@ protected function ensureColumn($columnName, Blueprint $table, array $blueprints
136137
return;
137138
}
138139

139-
throw new ImplicationException();
140-
} catch (ImplicationException $e) {
140+
throw new Exception();
141+
} catch (Exception $e) {
141142
$propertyReflection = new ReflectionProperty(
142143
$this->getReferencedModelName($modelNames),
143144
$this->references[0]
@@ -151,11 +152,11 @@ protected function ensureColumn($columnName, Blueprint $table, array $blueprints
151152
$referencedTable->$type($this->references[0]);
152153
return;
153154
}
154-
} catch (ImplicationException $e) {
155-
$table->unsignedBigInteger($columnName);
156155
} catch (Exception $e) {
157-
throw new ImplicationException(
158-
ImplicationException::CODE_FK_NO_COL,
156+
$table->unsignedBigInteger($columnName);
157+
} catch (BaseException $e) {
158+
throw new Exception(
159+
Exception::CODE_FK_NO_COL,
159160
[$this->columns[0], $table->getTable()],
160161
$e
161162
);
@@ -177,7 +178,7 @@ public function ensureColumns(Blueprint $table, array $blueprints, array $modelN
177178
$this->ensureColumn($columnName, $table, $blueprints, $modelNames);
178179
}
179180

180-
public function applyToBlueprint(Blueprint $table): Blueprint
181+
protected function process(Blueprint $table): Blueprint
181182
{
182183
$references = is_array($this->references) && count($this->references) === 1
183184
? $this->references[0]

src/Attributes/Index.php

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@
77
use Illuminate\Database\Schema\IndexDefinition;
88
use ReflectionProperty;
99
use Illuminate\Support\Str;
10-
use Toramanlis\ImplicitMigrations\Blueprint\IndexType;
11-
use Toramanlis\ImplicitMigrations\Exceptions\ImplicationException;
1210
use ValueError;
1311

1412
#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)]
1513
class Index extends MigrationAttribute
1614
{
15+
use Applicable;
16+
17+
1718
protected ?array $columns;
1819

1920
protected IndexType $type;
@@ -28,7 +29,7 @@ public function __construct(
2829
try {
2930
$this->type = IndexType::from(strtolower($type));
3031
} catch (ValueError $e) {
31-
throw new ImplicationException(ImplicationException::CODE_IDX_NO_TYPE, [$type], $e);
32+
throw new Exception(Exception::CODE_IDX_NO_TYPE, [$type], $e);
3233
}
3334

3435
$this->columns = is_string($column) ? [$column] : $column;
@@ -69,14 +70,14 @@ public function ensureColumns(Blueprint $table): void
6970
protected function validate(Blueprint $table)
7071
{
7172
if (empty($this->columns)) {
72-
throw new ImplicationException(
73-
ImplicationException::CODE_IDX_NO_COL,
73+
throw new Exception(
74+
Exception::CODE_IDX_NO_COL,
7475
[$table->getTable(), $this->type->name]
7576
);
7677
}
7778
}
7879

79-
public function applyToBlueprint(Blueprint $table): Blueprint
80+
protected function process(Blueprint $table): Blueprint
8081
{
8182
$this->validate($table);
8283

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
namespace Toramanlis\ImplicitMigrations\Blueprint;
3+
namespace Toramanlis\ImplicitMigrations\Attributes;
44

55
enum IndexType: string
66
{

src/Attributes/MigrationAttribute.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace Toramanlis\ImplicitMigrations\Attributes;
44

5+
use Illuminate\Support\Facades\Config;
6+
use Illuminate\Support\Str;
57
use ReflectionClass;
68
use ReflectionProperty;
79

@@ -18,4 +20,10 @@ public function inferFromReflectionClass(ReflectionClass $reflection): void
1820
public function inferFromExistingData(): void
1921
{
2022
}
23+
24+
public static function enabled(): bool
25+
{
26+
$key = Str::snake(last(explode('\\', static::class)));
27+
return Config::get("database.implications.{$key}", false);
28+
}
2129
}

src/Attributes/Primary.php

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,6 @@
33
namespace Toramanlis\ImplicitMigrations\Attributes;
44

55
use Attribute;
6-
use Illuminate\Database\Schema\Blueprint;
7-
use Illuminate\Database\Schema\IndexDefinition;
8-
use ReflectionProperty;
9-
use Illuminate\Support\Str;
10-
use Toramanlis\ImplicitMigrations\Blueprint\IndexType;
116

127
#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)]
138
class Primary extends Index

0 commit comments

Comments
 (0)