Skip to content

Commit ea33a94

Browse files
authored
Merge pull request #146 from kitloong/feature/has-table
Add `Schema::hasTable` option
2 parents be7b69e + 08ff816 commit ea33a94

File tree

10 files changed

+339
-24
lines changed

10 files changed

+339
-24
lines changed

.phpmd.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
</rule>
2929
<rule ref="rulesets/codesize.xml/ExcessiveClassComplexity">
3030
<properties>
31-
<property name="maximum" value="65"/>
31+
<property name="maximum" value="70"/>
3232
</properties>
3333
</rule>
3434
<rule ref="rulesets/codesize.xml/ExcessiveParameterList">

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,21 +119,24 @@ Run `php artisan help migrate:generate` for a list of options.
119119
| Options | Description |
120120
|--------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
121121
| -c, --connection[=CONNECTION] | The database connection to use |
122-
| -t, --tables[=TABLES] | A list of Tables or Views you wish to Generate Migrations for separated by a comma: users,posts,comments |
123-
| -i, --ignore[=IGNORE] | A list of Tables or Views you wish to ignore, separated by a comma: users,posts,comments |
122+
| -t, --tables[=TABLES] | A list of tables or views you wish to generate migrations for separated by a comma: users,posts,comments |
123+
| -i, --ignore[=IGNORE] | A list of tables or views you wish to ignore, separated by a comma: users,posts,comments |
124124
| -p, --path[=PATH] | Where should the file be created? |
125125
| -tp, --template-path[=TEMPLATE-PATH] | The location of the template for this generator |
126-
| --date[=DATE] | Migrations will be created with specified date. Views and Foreign keys will be created with + 1 second. Date should be in format supported by `Carbon::parse` |
126+
| --date[=DATE] | Migrations will be created with specified date. Views and foreign keys will be created with + 1 second. Date should be in format supported by `Carbon::parse` |
127127
| --table-filename[=TABLE-FILENAME] | Define table migration filename, default pattern: `[datetime]\_create_[name]_table.php` |
128128
| --view-filename[=VIEW-FILENAME] | Define view migration filename, default pattern: `[datetime]\_create_[name]_view.php` |
129129
| --proc-filename[=PROC-FILENAME] | Define stored procedure filename, default pattern: `[datetime]\_create_[name]_proc.php` |
130130
| --fk-filename[=FK-FILENAME] | Define foreign key migration filename, default pattern: `[datetime]\_add_foreign_keys_to_[name]_table.php` |
131+
| --log-with-batch[=LOG-WITH-BATCH] | Log migrations with given batch number. We recommend using batch number 0 so that it becomes the first migration |
131132
| --default-index-names | Don\'t use DB index names for migrations |
132133
| --default-fk-names | Don\'t use DB foreign key names for migrations |
133134
| --use-db-collation | Generate migrations with existing DB collation |
135+
| --skip-log | Don\'t log into migrations table |
134136
| --skip-views | Don\'t generate views |
135137
| --skip-proc | Don\'t generate stored procedures |
136138
| --squash | Generate all migrations into a single file |
139+
| --with-has-table | Check for the existence of a table using `hasTable` |
137140

138141
## SQLite Alter Foreign Key
139142

src/Enum/Migrations/Method/SchemaBuilder.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@
1111
* @method static self CONNECTION()
1212
* @method static self CREATE()
1313
* @method static self DROP_IF_EXISTS()
14+
* @method static self HAS_TABLE()
1415
* @method static self TABLE()
1516
*/
1617
final class SchemaBuilder extends Enum
1718
{
1819
private const CONNECTION = 'connection';
1920
private const CREATE = 'create';
2021
private const DROP_IF_EXISTS = 'dropIfExists';
22+
private const HAS_TABLE = 'hasTable';
2123
private const TABLE = 'table';
2224
}

src/MigrateGenerateCommand.php

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,23 +34,26 @@ class MigrateGenerateCommand extends Command
3434
* @var string
3535
*/
3636
protected $signature = 'migrate:generate
37-
{tables? : A list of Tables or Views you wish to Generate Migrations for separated by a comma: users,posts,comments}
37+
{tables? : A list of tables or views you wish to generate migrations for separated by a comma: users,posts,comments}
3838
{--c|connection= : The database connection to use}
39-
{--t|tables= : A list of Tables or Views you wish to Generate Migrations for separated by a comma: users,posts,comments}
40-
{--i|ignore= : A list of Tables or Views you wish to ignore, separated by a comma: users,posts,comments}
39+
{--t|tables= : A list of tables or views you wish to generate migrations for separated by a comma: users,posts,comments}
40+
{--i|ignore= : A list of tables or views you wish to ignore, separated by a comma: users,posts,comments}
4141
{--p|path= : Where should the file be created?}
4242
{--tp|template-path= : The location of the template for this generator}
43-
{--date= : Migrations will be created with specified date. Views and Foreign keys will be created with + 1 second. Date should be in format supported by Carbon::parse}
43+
{--date= : Migrations will be created with specified date. Views and foreign keys will be created with + 1 second. Date should be in format supported by Carbon::parse}
4444
{--table-filename= : Define table migration filename, default pattern: [datetime]_create_[name]_table.php}
4545
{--view-filename= : Define view migration filename, default pattern: [datetime]_create_[name]_view.php}
4646
{--proc-filename= : Define stored procedure migration filename, default pattern: [datetime]_create_[name]_proc.php}
4747
{--fk-filename= : Define foreign key migration filename, default pattern: [datetime]_add_foreign_keys_to_[name]_table.php}
48+
{--log-with-batch= : Log migrations with given batch number. We recommend using batch number 0 so that it becomes the first migration}
4849
{--default-index-names : Don\'t use DB index names for migrations}
4950
{--default-fk-names : Don\'t use DB foreign key names for migrations}
5051
{--use-db-collation : Generate migrations with existing DB collation}
52+
{--skip-log : Don\'t log into migrations table}
5153
{--skip-views : Don\'t generate views}
5254
{--skip-proc : Don\'t generate stored procedures}
53-
{--squash : Generate all migrations into a single file}';
55+
{--squash : Generate all migrations into a single file}
56+
{--with-has-table : Check for the existence of a table using `hasTable`}';
5457

5558
/**
5659
* The console command description.
@@ -142,10 +145,11 @@ protected function setup(string $connection): void
142145
{
143146
$setting = app(Setting::class);
144147
$setting->setDefaultConnection($connection);
145-
$setting->setUseDBCollation($this->option('use-db-collation'));
146-
$setting->setIgnoreIndexNames($this->option('default-index-names'));
147-
$setting->setIgnoreForeignKeyNames($this->option('default-fk-names'));
148+
$setting->setUseDBCollation((bool) $this->option('use-db-collation'));
149+
$setting->setIgnoreIndexNames((bool) $this->option('default-index-names'));
150+
$setting->setIgnoreForeignKeyNames((bool) $this->option('default-fk-names'));
148151
$setting->setSquash((bool) $this->option('squash'));
152+
$setting->setWithHasTable((bool) $this->option('with-has-table'));
149153

150154
$setting->setPath(
151155
$this->option('path') ?? Config::get('migrations-generator.migration_target_path')
@@ -277,13 +281,16 @@ protected function getExcludedTables(): array
277281
*
278282
* @param string $defaultConnection
279283
* @return void
284+
* @throws \Exception
280285
*/
281286
protected function askIfLogMigrationTable(string $defaultConnection): void
282287
{
283-
if (!$this->option('no-interaction')) {
284-
$this->shouldLog = $this->confirm('Do you want to log these migrations in the migrations table?', true);
288+
if ($this->skipInput()) {
289+
return;
285290
}
286291

292+
$this->shouldLog = $this->confirm('Do you want to log these migrations in the migrations table?', true);
293+
287294
if (!$this->shouldLog) {
288295
return;
289296
}
@@ -311,6 +318,32 @@ protected function askIfLogMigrationTable(string $defaultConnection): void
311318
);
312319
}
313320

321+
/**
322+
* Checks if should skip gather input from the user.
323+
*
324+
* @return bool
325+
* @throws \Exception
326+
*/
327+
protected function skipInput(): bool
328+
{
329+
if ($this->option('no-interaction') || $this->option('skip-log')) {
330+
return true;
331+
}
332+
333+
if ($this->option('log-with-batch') === null) {
334+
return false;
335+
}
336+
337+
if (!ctype_digit($this->option('log-with-batch'))) {
338+
throw new Exception('--log-with-batch must be a valid integer.');
339+
}
340+
341+
$this->shouldLog = true;
342+
$this->nextBatchNumber = (int) $this->option('log-with-batch');
343+
344+
return true;
345+
}
346+
314347
/**
315348
* Ask user for a Numeric Value, or blank for default.
316349
*

src/Migration/Blueprint/SchemaBlueprint.php

Lines changed: 73 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use KitLoong\MigrationsGenerator\Migration\Blueprint\Support\MethodStringHelper;
77
use KitLoong\MigrationsGenerator\Migration\Blueprint\Support\Stringable;
88
use KitLoong\MigrationsGenerator\Migration\Enum\Space;
9+
use KitLoong\MigrationsGenerator\Setting;
910
use KitLoong\MigrationsGenerator\Support\TableName;
1011

1112
/**
@@ -37,6 +38,8 @@ class SchemaBlueprint implements WritableBlueprint
3738
use TableName;
3839

3940
/**
41+
* The table name without prefix. {@see \Illuminate\Support\Facades\DB::getTablePrefix()}
42+
*
4043
* @var string
4144
*/
4245
private $table;
@@ -57,7 +60,7 @@ class SchemaBlueprint implements WritableBlueprint
5760
*/
5861
public function __construct(string $table, SchemaBuilder $schemaBuilder)
5962
{
60-
$this->table = $table;
63+
$this->table = $this->stripTablePrefix($table);
6164
$this->schemaBuilder = $schemaBuilder;
6265
$this->blueprint = null;
6366
}
@@ -86,19 +89,80 @@ private function getLines(): array
8689
{
8790
$schema = $this->connection('Schema', $this->schemaBuilder);
8891

89-
$tableWithoutPrefix = $this->stripTablePrefix($this->table);
92+
if ($this->schemaBuilder->equals(SchemaBuilder::DROP_IF_EXISTS())) {
93+
return $this->getDropLines($schema);
94+
}
95+
96+
$tableLines = $this->getTableLines($schema);
97+
98+
if (!app(Setting::class)->isWithHasTable()) {
99+
return $tableLines;
100+
}
101+
102+
$schemaHasTable = $this->connection('Schema', SchemaBuilder::HAS_TABLE());
90103

91104
$lines = [];
92105

93-
if ($this->blueprint !== null) {
94-
$lines[] = "$schema('$tableWithoutPrefix', function (Blueprint \$table) {";
95-
// Add 1 tabulation to indent(prettify) blueprint definition.
96-
$lines[] = Space::TAB() . $this->blueprint->toString();
97-
$lines[] = "});";
98-
return $lines;
106+
$lines[] = $this->getIfCondition($schemaHasTable, $this->table);
107+
108+
foreach ($tableLines as $tableLine) {
109+
// Add another tabulation to indent(prettify) blueprint definition.
110+
$lines[] = Space::TAB() . $tableLine;
111+
}
112+
113+
$lines[] = "}";
114+
115+
return $lines;
116+
}
117+
118+
/**
119+
* Get drop commands in array.
120+
*
121+
* @param string $schema The stringify `Schema::something` or `Schema::connection('db')->something`.
122+
* @return string[]
123+
*/
124+
private function getDropLines(string $schema): array
125+
{
126+
return [
127+
"$schema('$this->table');",
128+
];
129+
}
130+
131+
/**
132+
* Get table commands in array.
133+
*
134+
* @param string $schema The stringify `Schema::something` or `Schema::connection('db')->something`.
135+
* @return array
136+
*/
137+
private function getTableLines(string $schema): array
138+
{
139+
$lines = [];
140+
$lines[] = "$schema('$this->table', function (Blueprint \$table) {";
141+
142+
if (app(Setting::class)->isWithHasTable()) {
143+
$this->blueprint->increaseNumberOfPrefixTab();
99144
}
100145

101-
$lines[] = "$schema('$tableWithoutPrefix');";
146+
// Add 1 tabulation to indent(prettify) blueprint definition.
147+
$lines[] = Space::TAB() . $this->blueprint->toString();
148+
$lines[] = "});";
149+
102150
return $lines;
103151
}
152+
153+
/**
154+
* Generate `if` condition string.
155+
*
156+
* @param string $schemaHasTable The stringify `Schema::hasTable` or `Schema::connection('db')->hasTable`.
157+
* @param string $tableWithoutPrefix
158+
* @return string
159+
*/
160+
private function getIfCondition(string $schemaHasTable, string $tableWithoutPrefix): string
161+
{
162+
if ($this->schemaBuilder->equals(SchemaBuilder::TABLE())) {
163+
return "if ($schemaHasTable('$tableWithoutPrefix')) {";
164+
}
165+
166+
return "if (!$schemaHasTable('$tableWithoutPrefix')) {";
167+
}
104168
}

src/Migration/Blueprint/TableBlueprint.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ class TableBlueprint implements WritableBlueprint
3636
/** @var \KitLoong\MigrationsGenerator\Migration\Blueprint\Property[]|\KitLoong\MigrationsGenerator\Migration\Blueprint\Method[]|string[] */
3737
private $lines;
3838

39+
/**
40+
* By default, generate 3 tabs for each line.
41+
*
42+
* @var int
43+
*/
44+
private $numberOfPrefixTab = 3;
45+
3946
public function __construct()
4047
{
4148
$this->lines = [];
@@ -105,6 +112,16 @@ public function mergeTimestamps(): void
105112
$this->lines = $this->merge($this->lines, true);
106113
}
107114

115+
/**
116+
* Increase number of prefix tab by 1.
117+
*
118+
* @return void
119+
*/
120+
public function increaseNumberOfPrefixTab(): void
121+
{
122+
$this->numberOfPrefixTab++;
123+
}
124+
108125
/**
109126
* @inheritDoc
110127
*/
@@ -127,7 +144,7 @@ public function toString(): string
127144
}
128145
}
129146

130-
return $this->flattenLines($lines, 3);
147+
return $this->flattenLines($lines, $this->numberOfPrefixTab);
131148
}
132149

133150
/**

src/Setting.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ class Setting
4747
/** @var string */
4848
private $fkFilename;
4949

50+
/** @var bool */
51+
private $withHasTable;
52+
5053
/**
5154
* @return string
5255
*/
@@ -238,4 +241,20 @@ public function setDate(Carbon $date): void
238241
{
239242
$this->date = $date;
240243
}
244+
245+
/**
246+
* @return bool
247+
*/
248+
public function isWithHasTable(): bool
249+
{
250+
return $this->withHasTable;
251+
}
252+
253+
/**
254+
* @param bool $withHasTable
255+
*/
256+
public function setWithHasTable(bool $withHasTable): void
257+
{
258+
$this->withHasTable = $withHasTable;
259+
}
241260
}

0 commit comments

Comments
 (0)